diff options
| author | wdenk <wdenk> | 2003-09-10 22:30:53 +0000 | 
|---|---|---|
| committer | wdenk <wdenk> | 2003-09-10 22:30:53 +0000 | 
| commit | 7205e4075d8b50e4dd89fe39ed03860b23cbb704 (patch) | |
| tree | 0dfa865e7087ff4ee07967a2531c91ff5645a802 | |
| parent | 149dded2b178bc0fb62cb6f61b87968d914b580a (diff) | |
| download | olio-uboot-2014.01-7205e4075d8b50e4dd89fe39ed03860b23cbb704.tar.xz olio-uboot-2014.01-7205e4075d8b50e4dd89fe39ed03860b23cbb704.zip | |
* Patches by Denis Peter, 9 Sep 2003:U-Boot-0_4_8
  add FAT support for IDE, SCSI and USB
* Patches by Gleb Natapov, 2 Sep 2003:
  - cleanup of POST code for unsupported architectures
  - MPC824x locks way0 of data cache for use as initial RAM;
    this patch unlocks it after relocation to RAM and invalidates
    the locked entries.
* Patch by Gleb Natapov, 30 Aug 2003:
  new I2C driver for mpc107 bridge. Now works from flash.
* Patch by Dave Ellis, 11 Aug 2003:
  - JFFS2: fix typo in common/cmd_jffs2.c
  - JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option
  - JFFS2: remove node version 0 warning
  - JFFS2: accept JFFS2 PADDING nodes
  - SXNI855T: add AM29LV800 support
  - SXNI855T: move environment from EEPROM to flash
  - SXNI855T: boot from JFFS2 in NOR or NAND flash
* Patch by Bill Hargen, 11 Aug 2003:
  fixes for I2C on MPC8240
  - fix i2c_write routine
  - fix iprobe command
  - eliminates use of global variables, plus dead code, cleanup.
47 files changed, 1268 insertions, 2473 deletions
| @@ -2,6 +2,33 @@  Changes for U-Boot 0.4.8:  ====================================================================== +* Patches by Denis Peter, 9 Sep 2003: +  add FAT support for IDE, SCSI and USB + +* Patches by Gleb Natapov, 2 Sep 2003: +  - cleanup of POST code for unsupported architectures +  - MPC824x locks way0 of data cache for use as initial RAM; +    this patch unlocks it after relocation to RAM and invalidates +    the locked entries. + +* Patch by Gleb Natapov, 30 Aug 2003: +  new I2C driver for mpc107 bridge. Now works from flash. + +* Patch by Dave Ellis, 11 Aug 2003: +  - JFFS2: fix typo in common/cmd_jffs2.c +  - JFFS2: fix CFG_JFFS2_SORT_FRAGMENTS option +  - JFFS2: remove node version 0 warning +  - JFFS2: accept JFFS2 PADDING nodes +  - SXNI855T: add AM29LV800 support +  - SXNI855T: move environment from EEPROM to flash +  - SXNI855T: boot from JFFS2 in NOR or NAND flash + +* Patch by Bill Hargen, 11 Aug 2003: +  fixes for I2C on MPC8240 +  - fix i2c_write routine +  - fix iprobe command +  - eliminates use of global variables, plus dead code, cleanup. +  * Add support for USB Mass Storage Devices (BBB)    (tested with USB memory sticks only) @@ -302,3 +302,9 @@ W: www.elinos.com  N: Pantelis Antoniou  E: panto@intracom.gr  D: NETVIA board support, ARTOS support. + +N: Raghu Krishnaprasad +E: Raghu.Krishnaprasad@fci.com +D: Support for Adder-II MPC852T evaluation board +W: http://www.forcecomputers.com + diff --git a/MAINTAINERS b/MAINTAINERS index 20e68a831..006c73f15 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -108,6 +108,10 @@ Dave Ellis <DGE@sixnetio.com>  	SXNI855T		MPC8xx +Raghu Krishnaprasad <raghu.krishnaprasad@fci.com> +	 +	ADDERII			MPC852T +  Thomas Frieden <ThomasF@hyperion-entertainment.com>  	AmigaOneG3SE		MPC7xx diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index e2672f7b1..30dcdadde 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -375,138 +375,6 @@ void show_stdio_dev(void)  	}  } -/* ------------------------------------------------------------------------- */ - -	/* switches the cs0 and the cs1 to the locations. -	   When boot is TRUE, the the mapping is switched -	   to the boot configuration, If it is FALSE, the -	   flash will be switched in the boot area */ - -#undef SW_CS_DBG -#ifdef SW_CS_DBG -#define	SW_CS_PRINTF(fmt,args...)	printf (fmt ,##args) -#else -#define SW_CS_PRINTF(fmt,args...) -#endif - -#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) -int switch_cs(unsigned char boot) -{ -	unsigned long pbcr; -	int mode; - -	mode=get_boot_mode(); -	mtdcr(ebccfga, pb0cr); -	pbcr = mfdcr (ebccfgd); -	if (mode & BOOT_MPS) { -		/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */ -		/* we need only to switch if boot from MPS */ -		/* printf(" MPS boot mode detected. ");*/ -		/* printf("cs0 cfg: %lx\n",pbcr); */ -		if(boot) { -			/* switch to boot configuration */ -			/* this is a 8bit boot, switch cs0 to flash location */ -			SW_CS_PRINTF("switch to boot mode (MPS on High address\n"); -			pbcr&=0x000FFFFF; /*mask base address of the cs0 */ -			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000); -			mtdcr(ebccfga, pb0cr); -			mtdcr(ebccfgd, pbcr); -			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr); -			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */ -			pbcr = mfdcr(ebccfgd); -			SW_CS_PRINTF(" old cs1 cfg: %lx\n",pbcr); -			pbcr&=0x000FFFFF; /*mask base address of the cs1 */ -			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000); -			mtdcr(ebccfga, pb1cr); -			mtdcr(ebccfgd, pbcr); -			SW_CS_PRINTF("  new cs1 cfg: %lx, MPS is on High Address\n",pbcr); -		} -		else { -			/* map flash to boot area, */ -			SW_CS_PRINTF("map Flash to boot area\n"); -			pbcr&=0x000FFFFF; /*mask base address of the cs0 */ -			pbcr|=(MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000); -			mtdcr(ebccfga, pb0cr); -			mtdcr(ebccfgd, pbcr); -			SW_CS_PRINTF("  new cs0 cfg: %lx\n",pbcr); -			mtdcr(ebccfga, pb1cr); /* get cs1 config reg (flash) */ -			pbcr = mfdcr(ebccfgd); -			SW_CS_PRINTF("  cs1 cfg: %lx\n",pbcr); -			pbcr&=0x000FFFFF; /*mask base address of the cs1 */ -			pbcr|=(FLASH_BASE0_PRELIM & 0xFFF00000); -			mtdcr(ebccfga, pb1cr); -			mtdcr(ebccfgd, pbcr); -			SW_CS_PRINTF("  new cs1 cfg: %lx Flash is on High Address\n",pbcr); -		} -		return 1; -	} -	else { -		SW_CS_PRINTF("Normal boot, no switching necessary\n"); -		return 0; -	} - -} - -int get_boot_mode(void) -{ -	unsigned long pbcr; -	int res = 0; -	pbcr = mfdcr (strap); -	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) -		/* boot via MPS or MPS mapping */ -		res = BOOT_MPS; -	if(pbcr & PSR_ROM_LOC) -		/* boot via PCI.. */ -		res |= BOOT_PCI; -	 return res; -} - -/* Setup cs0 parameter finally. -   Map the flash high (in boot area) -   This code can only be executed from SDRAM (after relocation). -*/ -void setup_cs_reloc(void) -{ -	unsigned long pbcr; -	/* Since we are relocated, we can set-up the CS finaly -	 * but first of all, switch off PCI mapping (in case it was a PCI boot) */ -	out32r(PMM0MA,0L); -	icache_enable (); /* we are relocated */ -	/* for PCI Boot, we have to set-up the remaining CS correctly */ -	pbcr = mfdcr (strap); -	if(pbcr & PSR_ROM_LOC) { -		/* boot via PCI.. */ -		if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) { -		/* Boot width = 8 bit MPS Boot, set up MPS on CS0 */ -			#ifdef DEBUG -			printf("Mapping MPS to CS0 @ 0x%lx\n",(MPS_CR_B & 0xfff00000)); -			#endif -			mtdcr (ebccfga, pb0ap); -			mtdcr (ebccfgd, MPS_AP); -			mtdcr (ebccfga, pb0cr); -			mtdcr (ebccfgd, MPS_CR_B); -		} -		else { -			/* Flash boot, set up the Flash on CS0 */ -			#ifdef DEBUG -			printf("Mapping Flash to CS0 @ 0x%lx\n",(FLASH_CR_B & 0xfff00000)); -			#endif -			mtdcr (ebccfga, pb0ap); -			mtdcr (ebccfgd, FLASH_AP); -			mtdcr (ebccfga, pb0cr); -			mtdcr (ebccfgd, FLASH_CR_B); -		} -	} -	switch_cs(0); /* map Flash High */ -} - - -#elif defined(CONFIG_VCMA9) -int switch_cs(unsigned char boot) -{ -    return 0; -} -#endif /* CONFIG_VCMA9 */  int do_mplcommon(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  { @@ -625,6 +493,7 @@ void doc_init (void)  #ifdef CONFIG_CONSOLE_EXTRA_INFO  extern GraphicDevice ctfb; +extern int get_boot_mode(void);  void video_get_info_str (int line_number, char *info)  { diff --git a/board/mpl/common/common_util.h b/board/mpl/common/common_util.h index bcc79229f..8f2ec03f6 100644 --- a/board/mpl/common/common_util.h +++ b/board/mpl/common/common_util.h @@ -31,10 +31,8 @@ typedef struct {  } backup_t;  void get_backup_values(backup_t *buf); -int switch_cs(unsigned char boot); +  #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) -int get_boot_mode(void); -void setup_cs_reloc(void);  #define BOOT_MPS	0x01  #define BOOT_PCI	0x02  #endif diff --git a/board/mpl/common/flash.c b/board/mpl/common/flash.c index 4bdb8bdc6..99f97d773 100644 --- a/board/mpl/common/flash.c +++ b/board/mpl/common/flash.c @@ -39,6 +39,13 @@  #include <ppc4xx.h>  #include <asm/processor.h>  #include "common_util.h" +#if defined(CONFIG_MIP405) +#include "../mip405/mip405.h" +#endif +#if defined(CONFIG_PIP405) +#include "../pip405/pip405.h" +#endif +#include <405gp_pci.h>  flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/  /*----------------------------------------------------------------------- @@ -66,23 +73,102 @@ void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt);  #define TRUE            1  /*----------------------------------------------------------------------- + * Some CS switching routines: + * + * On PIP/MIP405 we have 3 (4) possible boot mode + * + * - Boot from Flash (Flash CS = CS0, MPS CS = CS1) + * - Boot from MPS   (Flash CS = CS1, MPS CS = CS0) + * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1) + * - Boot from PCI with MPS map   (Flash CS = CS1, MPS CS = CS0) + * The flash init is the first board specific routine which is called + * after code relocation (running from SDRAM) + * The first thing we do is to map the Flash CS to the Flash area and + * the MPS CS to the MPS area. Since the flash size is unknown at this + * point, we use the max flash size and the lowest flash address as base. + *  + * After flash detection we adjust the size of the CS area accordingly. + * The board_init_r will fill in wrong values in the board init structure, + * but this will be fixed in the misc_init_r routine: + * bd->bi_flashstart=0-flash_info[0].size + * bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN + * bd->bi_flashoffset=0 + *    */ +int get_boot_mode(void) +{ +	unsigned long pbcr; +	int res = 0; +	pbcr = mfdcr (strap); +	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) +		/* boot via MPS or MPS mapping */ +		res = BOOT_MPS; +	if(pbcr & PSR_ROM_LOC) +		/* boot via PCI.. */ +		res |= BOOT_PCI; +	 return res; +} + +/* Map the flash high (in boot area) +   This code can only be executed from SDRAM (after relocation). +*/ +void setup_cs_reloc(void) +{ +	int mode; +	/* Since we are relocated, we can set-up the CS finaly +	 * but first of all, switch off PCI mapping (in case it was a PCI boot) */ +	out32r(PMM0MA,0L); +	icache_enable (); /* we are relocated */ +	/* get boot mode */ +	mode=get_boot_mode(); +	/* we map the flash high in every case */ +	/* first findout on which cs the flash is */ +	if(mode & BOOT_MPS) { +		/* map flash high on CS1 and MPS on CS0 */ +		mtdcr (ebccfga, pb0ap); +		mtdcr (ebccfgd, MPS_AP); +		mtdcr (ebccfga, pb0cr); +		mtdcr (ebccfgd, MPS_CR); +		/* we use the default values (max values) for the flash +		 * because its real size is not yet known */ +		mtdcr (ebccfga, pb1ap); +		mtdcr (ebccfgd, FLASH_AP); +		mtdcr (ebccfga, pb1cr); +		mtdcr (ebccfgd, FLASH_CR_B); +	} +	else { +		/* map flash high on CS0 and MPS on CS1 */ +		mtdcr (ebccfga, pb1ap); +		mtdcr (ebccfgd, MPS_AP); +		mtdcr (ebccfga, pb1cr); +		mtdcr (ebccfgd, MPS_CR); +		/* we use the default values (max values) for the flash +		 * because its real size is not yet known */ +		mtdcr (ebccfga, pb0ap); +		mtdcr (ebccfgd, FLASH_AP); +		mtdcr (ebccfga, pb0cr); +		mtdcr (ebccfgd, FLASH_CR_B); +	} +} +  unsigned long flash_init (void)  { -	unsigned long size_b0, size_b1; -	int i; +	unsigned long size_b0, size_b1,flashcr; +	int mode, i; +	extern char version_string; +	char *p=&version_string;  	/* Since we are relocated, we can set-up the CS finally */  	setup_cs_reloc();  	/* get and display boot mode */ -	i=get_boot_mode(); -	if(i & BOOT_PCI) -		printf("(PCI Boot %s Map) ",(i & BOOT_MPS) ? +	mode=get_boot_mode(); +	if(mode & BOOT_PCI) +		printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ?  			"MPS" : "Flash");  	else -		printf("(%s Boot) ",(i & BOOT_MPS) ? +		printf("(%s Boot) ",(mode & BOOT_MPS) ?  			"MPS" : "Flash");  	/* Init: no FLASHes known */  	for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) { @@ -91,7 +177,7 @@ unsigned long flash_init (void)  	/* Static FLASH Bank configuration here - FIXME XXX */ -	size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); +	size_b0 = flash_get_size((vu_long *)CFG_MONITOR_BASE, &flash_info[0]);  	if (flash_info[0].flash_id == FLASH_UNKNOWN) {  		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", @@ -109,8 +195,31 @@ unsigned long flash_init (void)  	flash_info[0].protect[flash_info[0].sector_count-1] = 1;  	size_b1 = 0 ;  	flash_info[0].size = size_b0; +	/* set up flash cs according to the size */ +	if(mode & BOOT_MPS) { +		/* flash is on CS1 */ +		mtdcr(ebccfga, pb1cr); +		flashcr = mfdcr (ebccfgd); +		/* we map the flash high in every case */ +		flashcr&=0x0001FFFF; /* mask out address bits */ +		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */ +		flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */ +		mtdcr(ebccfga, pb1cr); +		mtdcr(ebccfgd, flashcr); +	} +	else { +		/* flash is on CS0 */ +		mtdcr(ebccfga, pb0cr); +		flashcr = mfdcr (ebccfgd); +		/* we map the flash high in every case */ +		flashcr&=0x0001FFFF; /* mask out address bits */ +		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */ +		flashcr|= (((flash_info[0].size >>21) & 0x07) << 17); /* size addr */ +		mtdcr(ebccfga, pb0cr); +		mtdcr(ebccfgd, flashcr); +	}  #if 0 -	/* include this if you want to test if +	/* enable this if you want to test if  	   the relocation has be done ok.  	   This will disable both Chipselects */  	mtdcr (ebccfga, pb0cr); @@ -119,6 +228,14 @@ unsigned long flash_init (void)  	mtdcr (ebccfgd, 0L);  	printf("CS0 & CS1 switched off for test\n");  #endif +	/* patch version_string */ +	for(i=0;i<0x100;i++) { +		if(*p=='\n') { +			*p=0; +			break; +		} +		p++; +	}  	return (size_b0);  } @@ -171,6 +288,8 @@ void flash_print_info  (flash_info_t *info)  				break;  	case FLASH_INTEL320T:	printf ("TE28F320C3 (32 Mbit, top sector size)\n");  				break; +	case FLASH_AM640U:	printf ("AM29LV640U (64 Mbit, uniform sector size)\n"); +				break;  	default:		printf ("Unknown Chip Type\n");  				break;  	} @@ -211,7 +330,8 @@ void flash_print_info  (flash_info_t *info)  /*----------------------------------------------------------------------- - */ +  +*/  /*   * The following code cannot be run from FLASH! @@ -220,7 +340,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)  {  	short i;  	FLASH_WORD_SIZE value; -	ulong base = (ulong)addr; +	ulong base;  	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr;  	/* Write auto select command: read Manufacturer ID */ @@ -250,7 +370,7 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)  		return (0);			/* no or unknown flash	*/  	}  	value = addr2[1];			/* device ID		*/ -	/*	printf("Device value %x\n",value); */ +	/*	printf("Device value %x\n",value); 		    */  	switch (value) {  	case (FLASH_WORD_SIZE)AMD_ID_F040B:  		info->flash_id += FLASH_AM040; @@ -292,12 +412,17 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)  		info->sector_count = 35;  		info->size = 0x00200000;  		break;				/* => 2 MB		*/ -#if 0	/* enable when device IDs are available */  	case (FLASH_WORD_SIZE)AMD_ID_LV320T:  		info->flash_id += FLASH_AM320T;  		info->sector_count = 67;  		info->size = 0x00400000;  		break;				/* => 4 MB		*/ +	case (FLASH_WORD_SIZE)AMD_ID_LV640U: +		info->flash_id += FLASH_AM640U; +		info->sector_count = 128; +		info->size = 0x00800000; +		break;				/* => 8 MB		*/ +#if 0	/* enable when device IDs are available */  	case (FLASH_WORD_SIZE)AMD_ID_LV320B:  		info->flash_id += FLASH_AM320B; @@ -328,10 +453,12 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)  		return (0);			/* => no or unknown flash */  	} - +	/* base address calculation */ +	base=0-info->size;  	/* set up sector start address table */  	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || -	     (info->flash_id  == FLASH_AM040)){ +	     (info->flash_id  == FLASH_AM040) || +	     (info->flash_id  == FLASH_AM640U)){  		for (i = 0; i < info->sector_count; i++)  			info->start[i] = base + (i * 0x00010000);  	} diff --git a/board/mpl/common/isa.c b/board/mpl/common/isa.c index 1788d5117..793c34fe2 100644 --- a/board/mpl/common/isa.c +++ b/board/mpl/common/isa.c @@ -32,7 +32,6 @@  #include "kbd.h"  #include "video.h" -extern int drv_isa_kbd_init (void);  #undef	ISA_DEBUG @@ -49,6 +48,9 @@ extern int drv_isa_kbd_init (void);  #define FALSE           0  #endif +#if defined(CONFIG_PIP405) + +extern int drv_isa_kbd_init (void);  /* fdc (logical device 0) */  const SIO_LOGDEV_TABLE sio_fdc[] = { @@ -183,7 +185,7 @@ void isa_sio_setup(void)  		close_cfg_super_IO(0x3F0);  	}  } - +#endif  /******************************************************************************   * IRQ Controller @@ -202,7 +204,7 @@ static struct isa_irq_action isa_irqs[16];  /*   * This contains the irq mask for both 8259A irq controllers,   */ -static unsigned int cached_irq_mask = 0xffff; +static unsigned int cached_irq_mask = 0xfff9;  #define cached_imr1	(unsigned char)cached_irq_mask  #define cached_imr2	(unsigned char)(cached_irq_mask>>8) @@ -387,19 +389,22 @@ int handle_isa_int(void)  	isr2=in8(ISR_2);  	isr1=in8(ISR_1);  	irq=(unsigned char)irqack; -	if((irq==7)&&((isr1&0x80)==0)) { +	irq-=32; +/*	if((irq==7)&&((isr1&0x80)==0)) {  		PRINTF("IRQ7 detected but not in ISR\n");  	}  	else { -		/* we should handle cascaded interrupts here also */ -		/* printf("ISA Irq %d\n",irq); */ -		isa_irqs[irq].count++; -	if (isa_irqs[irq].handler != NULL) -		(*isa_irqs[irq].handler)(isa_irqs[irq].arg);      /* call isr */ -	else +*/		/* we should handle cascaded interrupts here also */  	{ -	PRINTF ("bogus interrupt vector 0x%x\n", irq); -	} +/*		printf("ISA Irq %d\n",irq); */ +		isa_irqs[irq].count++; +		if(irq!=2) { /* just swallow the cascade irq 2 */ +			if (isa_irqs[irq].handler != NULL) +				(*isa_irqs[irq].handler)(isa_irqs[irq].arg);      /* call isr */ +			else { +				PRINTF ("bogus interrupt vector 0x%x\n", irq); +			} +		}  	}  	/* issue EOI instruction to clear the IRQ */  	mask_and_ack_8259A(irq); @@ -413,13 +418,13 @@ int handle_isa_int(void)  void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)  { -  if (isa_irqs[vec].handler != NULL) { -   printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n", -	   vec, (uint)handler, (uint)isa_irqs[vec].handler); -  } -  isa_irqs[vec].handler = handler; -  isa_irqs[vec].arg     = arg; -  enable_8259A_irq(vec); +	if (isa_irqs[vec].handler != NULL) { +		printf ("ISA Interrupt vector %d: handler 0x%x replacing 0x%x\n", +			vec, (uint)handler, (uint)isa_irqs[vec].handler); +	} +	isa_irqs[vec].handler = handler; +	isa_irqs[vec].arg     = arg; +	enable_8259A_irq(vec);  	PRINTF ("Install ISA IRQ %d ==> %p, @ %p mask=%04x\n", vec, handler, &isa_irqs[vec].handler,cached_irq_mask);  } @@ -427,9 +432,9 @@ void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg)  void isa_irq_free_handler(int vec)  {  	disable_8259A_irq(vec); -  isa_irqs[vec].handler = NULL; -  isa_irqs[vec].arg     = NULL; -	printf ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask); +	isa_irqs[vec].handler = NULL; +	isa_irqs[vec].arg     = NULL; +	PRINTF ("Free ISA IRQ %d mask=%04x\n", vec, cached_irq_mask);  } @@ -448,16 +453,42 @@ void isa_init_irq_contr(void)  	init_8259A();  	out8(IMR_2,0xFF);  } +/*************************************************************************/ +void isa_show_irq(void) +{ +	int vec; + +	printf ("\nISA Interrupt-Information:\n"); +	printf ("Nr  Routine   Arg       Count\n"); + +	for (vec=0; vec<16; vec++) { +		if (isa_irqs[vec].handler != NULL) { +			printf ("%02d  %08lx  %08lx  %d\n", +				vec, +				(ulong)isa_irqs[vec].handler, +				(ulong)isa_irqs[vec].arg, +				isa_irqs[vec].count); +		} +	} +} + +int isa_irq_get_count(int vec) +{ +	return(isa_irqs[vec].count); +}  /******************************************************************   * Init the ISA bus and devices.   */ +#if defined(CONFIG_PIP405)  int isa_init(void)  {  	isa_sio_setup(); +	isa_init_irq_contr();  	drv_isa_kbd_init();  	return 0;  } +#endif diff --git a/board/mpl/common/isa.h b/board/mpl/common/isa.h index 578222d44..28ed21915 100644 --- a/board/mpl/common/isa.h +++ b/board/mpl/common/isa.h @@ -21,12 +21,12 @@   * MA 02111-1307 USA   */ -#ifndef _PIP405_ISA_H_ -#define _PIP405_ISA_H_ +#ifndef _ISA_H_ +#define _ISA_H_  /* Super IO */  #define SIO_CFG_PORT	0x3F0	/* Config Port Address */ - +#if defined(CONFIG_PIP405)  /* table fore SIO initialization */  typedef struct {  	const uchar index; @@ -44,10 +44,14 @@ unsigned char read_cfg_super_IO(int address, unsigned char function, unsigned ch  void write_cfg_super_IO(int address, unsigned char function, unsigned char regaddr, unsigned char data);  void close_cfg_super_IO(int address);  void isa_sio_setup(void); -void isa_sio_setup(void); +#endif +  void isa_irq_install_handler(int vec, interrupt_handler_t *handler, void *arg);  void isa_irq_free_handler(int vec);  int handle_isa_int(void); +void isa_init_irq_contr(void); +void isa_show_irq(void); +int isa_irq_get_count(int vec);  #endif diff --git a/board/mpl/common/pci_parts.h b/board/mpl/common/pci_parts.h index e5627aa34..a57b12156 100644 --- a/board/mpl/common/pci_parts.h +++ b/board/mpl/common/pci_parts.h @@ -92,7 +92,7 @@ extern void pci_pip405_write_regs(struct pci_controller *,  /* PIIX4 ISA Bridge Function 0 */  static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {  	{PCI_CFG_PIIX4_SERIRQ,	0xD0,		1}, /* enable Continous SERIRQ Pin */ -	{PCI_CFG_PIIX4_GENCFG,	0x00010041,	4}, /* enable SERIRQs, ISA, PNP	*/ +	{PCI_CFG_PIIX4_GENCFG,	0x00018041,	4}, /* enable SERIRQs, ISA, PNP, GPI11 */  	{PCI_CFG_PIIX4_TOM,	0xFE,		1}, /* Top of Memory		*/  	{PCI_CFG_PIIX4_XBCS,	0x02C4,		2}, /* disable all peri CS	*/  	{PCI_CFG_PIIX4_RTCCFG,	0x21,		1}, /* enable RTC	   	*/ @@ -106,6 +106,7 @@ static struct pci_pip405_config_entry piix4_isa_bridge_f0[] = {  /* PIIX4 IDE Controller Function 1 */  static struct pci_pip405_config_entry piix4_ide_cntrl_f1[] = { +	{PCI_CFG_PIIX4_BMIBA,	0x0001000,	4}, /* set BMI to a valid address */  	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/  #if !defined(CONFIG_MIP405T)  	{PCI_CFG_PIIX4_IDETIM,	0x80008000,	4}, /* enable Both IDE channels	*/ @@ -129,10 +130,10 @@ static struct pci_pip405_config_entry piix4_usb_cntrl_f2[] = {  /* PIIX4 Power Management Function 3 */  static struct pci_pip405_config_entry piix4_pmm_cntrl_f3[] = { -	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/ -	{PCI_CFG_PIIX4_PMAB,	0x00004000,	4}, /* set PMBA to "valid" value */ -	{PCI_CFG_PIIX4_PMMISC,	0x01,		1}, /* enable PMBA IO access	*/ +	{PCI_CFG_PIIX4_PMBA,	0x00004000,	4}, /* set PMBA to "valid" value */  	{PCI_CFG_PIIX4_SMBBA,	0x00005000,	4}, /* set SMBBA to "valid" value */ +	{PCI_CFG_PIIX4_PMMISC,	0x01,		1}, /* enable PMBA IO access	*/ +	{PCI_COMMAND,		0x0001,		2}, /* enable IO access 	*/  	{ }					    /* end of device table 	*/  };  /* PPC405 Dummy only used to prevent autosetup on this host bridge */ diff --git a/board/mpl/common/piix4_pci.h b/board/mpl/common/piix4_pci.h index 3c0523f25..0ff802e74 100644 --- a/board/mpl/common/piix4_pci.h +++ b/board/mpl/common/piix4_pci.h @@ -143,7 +143,7 @@  #define	PCI_CFG_PIIX4_LEGSUP	0xC0  /* Function 3 Power Management */ -#define	PCI_CFG_PIIX4_PMAB		0x40 +#define	PCI_CFG_PIIX4_PMBA		0x40  #define	PCI_CFG_PIIX4_CNTA		0x44  #define	PCI_CFG_PIIX4_CNTB		0x48  #define	PCI_CFG_PIIX4_GPICTL	0x4C diff --git a/board/mpl/mip405/cmd_mip405.c b/board/mpl/mip405/cmd_mip405.c index 0f28fa2bf..6fbc5859c 100644 --- a/board/mpl/mip405/cmd_mip405.c +++ b/board/mpl/mip405/cmd_mip405.c @@ -54,10 +54,13 @@ int do_mip405(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	return (do_mplcommon(cmdtp, flag, argc, argv));  }  U_BOOT_CMD( -	mip405,	6,	1,	do_mip405, +	mip405,	8,	1,	do_mip405,  	"mip405  - MIP405 specific Cmds\n",  	"flash mem [SrcAddr] - updates U-Boot with image in memory\n"  	"mip405 flash mps - updates U-Boot with image from MPS\n" +	"mip405 info      - displays board information\n" +	"mip405 led <on>  - switches LED on (on=1) or off (on=0)\n" +	"mip405 mem [cnt] - Memory Test <cnt>-times, <cnt> = -1 loop forever\n"  );  /* ------------------------------------------------------------------------- */ diff --git a/board/mpl/mip405/init.S b/board/mpl/mip405/init.S index 00bf739b0..3351b5b84 100644 --- a/board/mpl/mip405/init.S +++ b/board/mpl/mip405/init.S @@ -87,19 +87,15 @@ ext_bus_cntlr_init:  	mfdcr		r4,ebccfgd  	andi.		r0, r4, 0x2000			/* mask out irrelevant bits */ -	beq			0f						/* jump if 8 bit bus width */ +	beq		0f				/* jump if 8 bit bus width */ -	/* setup 16 bit things (Flash Boot) +	/* setup 16 bit things     *-----------------------------------------------------------------------     * Memory Bank 0 (16 Bit Flash) initialization     *---------------------------------------------------------------------- */  	addi    r4,0,pb0ap  	mtdcr   ebccfga,r4 -/*	addis   r4,0,0xFF8F */ -/*	ori     r4,r4,0xFE80 */ -/*	addis   r4,0,0x9B01 */ -/*	ori     r4,r4,0x5480 */  	addis   r4,0,(FLASH_AP_B)@h  	ori     r4,r4,(FLASH_AP_B)@l  	mtdcr   ebccfgd,r4 @@ -107,8 +103,6 @@ ext_bus_cntlr_init:  	addi    r4,0,pb0cr  	mtdcr   ebccfga,r4  	/* BS=0x010(4MB),BU=0x3(R/W), */ -/*	addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */ -/*	ori     r4,r4,0xA000          / * BW=0x01(16 bits) */  	addis   r4,0,(FLASH_CR_B)@h  	ori     r4,r4,(FLASH_CR_B)@l  	mtdcr   ebccfgd,r4 @@ -123,21 +117,13 @@ ext_bus_cntlr_init:  	/* 0x7F8FFE80 slowest boot */  	addi    r4,0,pb0ap  	mtdcr   ebccfga,r4 -#if 0 -	addis   r4,0,0x9B01 -	ori     r4,r4,0x5480 -#else  	addis   r4,0,(MPS_AP_B)@h  	ori     r4,r4,(MPS_AP_B)@l -#endif  	mtdcr   ebccfgd,r4  	addi    r4,0,pb0cr  	mtdcr   ebccfga,r4  	/* BS=0x010(4MB),BU=0x3(R/W), */ -/*	addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h */ -/*	ori     r4,r4,0x8000          / * BW=0x0( 8 bits) */ -  	addis   r4,0,(MPS_CR_B)@h  	ori     r4,r4,(MPS_CR_B)@l @@ -178,18 +164,18 @@ ext_bus_cntlr_init:    ori     r4,r4,0x0000    mtdcr   ebccfgd,r4 -	addi    r4,0,pb6cr +  addi    r4,0,pb6cr    mtdcr   ebccfga,r4    addis   r4,0,0x0000    ori     r4,r4,0x0000    mtdcr   ebccfgd,r4 -	addi    r4,0,pb7cr +  addi    r4,0,pb7cr    mtdcr   ebccfga,r4    addis   r4,0,0x0000    ori     r4,r4,0x0000    mtdcr   ebccfgd,r4 -	nop				/* pass2 DCR errata #8 */ +  nop				/* pass2 DCR errata #8 */    blr  /*----------------------------------------------------------------------------- diff --git a/board/mpl/mip405/mip405.c b/board/mpl/mip405/mip405.c index 090041b40..70eb5f4dc 100644 --- a/board/mpl/mip405/mip405.c +++ b/board/mpl/mip405/mip405.c @@ -667,9 +667,16 @@ static int test_dram (unsigned long ramsize)  /* used to check if the time in RTC is valid */  static unsigned long start;  static struct rtc_time tm; +extern flash_info_t flash_info[];	/* info for FLASH chips */  int misc_init_r (void)  { +	DECLARE_GLOBAL_DATA_PTR; +	/* adjust flash start and size as well as the offset */ +	gd->bd->bi_flashstart=0-flash_info[0].size; +	gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN; +	gd->bd->bi_flashoffset=0; +  	/* check, if RTC is running */  	rtc_get (&tm);  	start=get_timer(0); diff --git a/board/mpl/mip405/mip405.h b/board/mpl/mip405/mip405.h index f1e37ff8d..b1d91deec 100644 --- a/board/mpl/mip405/mip405.h +++ b/board/mpl/mip405/mip405.h @@ -137,13 +137,13 @@ void user_led0(unsigned char on);  					(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))  /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ -#define FLASH_BS	2	/* 4 MByte */ +#define FLASH_BS	FLASH_SIZE_PRELIM	/* 4 MByte */  /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */  #define FLASH_BU	3	/* R/W */  /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */  #define FLASH_BW	1	/* 16Bit */  /* CR register for Boot */ -#define FLASH_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) +#define FLASH_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))  /* CR register for non Boot */  #define FLASH_CR	((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) @@ -172,11 +172,12 @@ void user_led0(unsigned char on);  /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */  #define MPS_BS		2	/* 4 MByte */ +#define MPS_BS_B		FLASH_SIZE_PRELIM	/* 1 MByte */  /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */  #define MPS_BU		3	/* R/W */  /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */  #define MPS_BW		0	/* 8Bit */  /* CR register for Boot */ -#define MPS_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) +#define MPS_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS_B << 17) + (MPS_BU << 15) + (MPS_BW << 13))  /* CR register for non Boot */  #define MPS_CR		((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) diff --git a/board/mpl/pip405/init.S b/board/mpl/pip405/init.S index a0c76dd20..39f2ea534 100644 --- a/board/mpl/pip405/init.S +++ b/board/mpl/pip405/init.S @@ -41,17 +41,21 @@  #define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/ -#include "configs/PIP405.h" +#include <configs/PIP405.h>  #include <ppc_asm.tmpl>  #include <ppc_defs.h>  #include <asm/cache.h>  #include <asm/mmu.h> +#include "pip405.h" +  .globl ext_bus_cntlr_init + ext_bus_cntlr_init: +  mflr   r4                      /* save link register */ +  mfdcr  r3,strap                /* get strapping reg */ +  andi.  r0, r3, PSR_ROM_LOC     /* mask out irrelevant bits */ +  bnelr                          /* jump back if PCI boot */ -	.globl	ext_bus_cntlr_init -ext_bus_cntlr_init: -  mflr    r4                      /* save link register */    bl      ..getAddr  ..getAddr:    mflr    r3                      /* get address of ..getAddr */ @@ -82,7 +86,7 @@ ext_bus_cntlr_init:  	mfdcr		r4,ebccfgd  	andi.		r0, r4, 0x2000			/* mask out irrelevant bits */ -	beq			0f									/* jump if 8 bit bus width */ +	beq		0f				/* jump if 8 bit bus width */  	/* setup 16 bit things     *----------------------------------------------------------------------- @@ -90,74 +94,49 @@ ext_bus_cntlr_init:     *---------------------------------------------------------------------- */  	addi    r4,0,pb0ap -  mtdcr   ebccfga,r4 -  addis   r4,0,0x9B01 -  ori     r4,r4,0x5480 -  mtdcr   ebccfgd,r4 - -  addi    r4,0,pb0cr -  mtdcr   ebccfga,r4 -	/* BS=0x011(8MB),BU=0x3(R/W), */ -  addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h -  ori     r4,r4,0xA000          /* BW=0x01(16 bits) */ -  mtdcr   ebccfgd,r4 +	mtdcr   ebccfga,r4 +	addis   r4,0,(FLASH_AP_B)@h +	ori     r4,r4,(FLASH_AP_B)@l +	mtdcr   ebccfgd,r4 -  /*----------------------------------------------------------------------- -   * Memory Bank 1 (Multi Purpose Socket) initialization -   *----------------------------------------------------------------------*/ -  addi    r4,0,pb1ap -  mtdcr   ebccfga,r4 -  addis   r4,0,0x0281 -  ori     r4,r4,0x5480 -  mtdcr   ebccfgd,r4 - -  addi    r4,0,pb1cr -  mtdcr   ebccfga,r4 -  /* BS=0x011(8MB),BU=0x3(R/W), */ -  addis   r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h -  ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */ -  mtdcr   ebccfgd,r4 +	addi    r4,0,pb0cr +	mtdcr   ebccfga,r4 +	/* BS=0x010(4MB),BU=0x3(R/W), */ +	addis   r4,0,(FLASH_CR_B)@h +	ori     r4,r4,(FLASH_CR_B)@l +	mtdcr   ebccfgd,r4  	b				1f  0: -  /* 8Bit boot mode: */ +	/* 8Bit boot mode: */  	/*----------------------------------------------------------------------- -   * Memory Bank 0 Multi Purpose Socket initialization -   *----------------------------------------------------------------------- */ - +	* Memory Bank 0 Multi Purpose Socket initialization +	*----------------------------------------------------------------------- */ +	/* 0x7F8FFE80 slowest boot */  	addi    r4,0,pb0ap -  mtdcr   ebccfga,r4 -  addis   r4,0,0x9B01 -  ori     r4,r4,0x5480 -  mtdcr   ebccfgd,r4 +	mtdcr   ebccfga,r4 +	addis   r4,0,(MPS_AP_B)@h +	ori     r4,r4,(MPS_AP_B)@l +	mtdcr   ebccfgd,r4 -  addi    r4,0,pb0cr -  mtdcr   ebccfga,r4 -	/* BS=0x011(4MB),BU=0x3(R/W), */ -  addis   r4,0,((FLASH_BASE0_PRELIM & 0xFFF00000) | 0x00050000)@h -  ori     r4,r4,0x8000          /* BW=0x0( 8 bits) */ -  mtdcr   ebccfgd,r4 +	addi    r4,0,pb0cr +	mtdcr   ebccfga,r4 +	/* BS=0x010(4MB),BU=0x3(R/W), */ +	addis   r4,0,(MPS_CR_B)@h +	ori     r4,r4,(MPS_CR_B)@l +	mtdcr   ebccfgd,r4 + +1:    /*----------------------------------------------------------------------- -   * Memory Bank 1 (Flash) initialization +   * Memory Bank 2-3-4-5-6 (not used) initialization     *-----------------------------------------------------------------------*/ -  addi    r4,0,pb1ap -  mtdcr   ebccfga,r4 -  addis   r4,0,0x0281 -  ori     r4,r4,0x5480 -  mtdcr   ebccfgd,r4 -    addi    r4,0,pb1cr    mtdcr   ebccfga,r4 -  /* BS=0x011(8MB),BU=0x3(R/W), */ -  addis   r4,0,((MULTI_PURPOSE_SOCKET_ADDR & 0xFFF00000) | 0x00050000)@h -  ori     r4,r4,0xA000          /* BW=0x0( 8 bits) */ +  addis   r4,0,0x0000 +  ori     r4,r4,0x0000    mtdcr   ebccfgd,r4 -1: -  /*----------------------------------------------------------------------- -   * Memory Bank 2-3-4-5-6 (not used) initialization -   *-----------------------------------------------------------------------*/    addi    r4,0,pb2cr    mtdcr   ebccfga,r4    addis   r4,0,0x0000 @@ -182,28 +161,18 @@ ext_bus_cntlr_init:    ori     r4,r4,0x0000    mtdcr   ebccfgd,r4 -	addi    r4,0,pb6cr +  addi    r4,0,pb6cr    mtdcr   ebccfga,r4    addis   r4,0,0x0000    ori     r4,r4,0x0000    mtdcr   ebccfgd,r4 -	/*----------------------------------------------------------------------- -   * Memory Bank 7 (Config Register) initialization -   *----------------------------------------------------------------------- */ -  addi    r4,0,pb7ap -  mtdcr   ebccfga,r4 -  addis   r4,0,0x0181	      /* Doc says TWT=3 and Openios TWT=3!! */ -  ori     r4,r4,0x5280          /* disable Ready, BEM=0 */ -  mtdcr   ebccfgd,r4 -    addi    r4,0,pb7cr    mtdcr   ebccfga,r4 -	/* BS=0x0(1MB),BU=0x3(R/W), */ -  addis   r4,0,((CONFIG_PORT_ADDR & 0xFFF00000) | 0x00010000)@h -  ori     r4,r4,0x8000            /* BW=0x0(8 bits) */ +  addis   r4,0,0x0000 +  ori     r4,r4,0x0000    mtdcr   ebccfgd,r4 -	nop				/* pass2 DCR errata #8 */ +  nop				/* pass2 DCR errata #8 */    blr  /*----------------------------------------------------------------------------- @@ -217,3 +186,45 @@ sdram_init:    blr + + +#if defined(CONFIG_BOOT_PCI) +    .section .bootpg,"ax" +    .globl _start_pci +/******************************************* + */ + +_start_pci: +  /* first handle errata #68 / PCI_18 */ +  iccci   r0, r0          /* invalidate I-cache */ +  lis     r31, 0 +  mticcr  r31             /* ICCR = 0 (all uncachable) */ +  isync + +  mfccr0  r28             /* set CCR0[24] = 1 */ +  ori     r28, r28, 0x0080 +  mtccr0  r28 + +  /* setup PMM0MA (0xEF400004) and PMM0PCIHA (0xEF40000C) */ +  lis     r28, 0xEF40 +  addi    r28, r28, 0x0004 +  stw     r31, 0x0C(r28)  /* clear PMM0PCIHA */ +  lis     r29, 0xFFF8     /* open 512 kByte */ +  addi    r29, r29, 0x0001/* and enable this region */ +  stwbrx  r29, r0, r28    /* write PMM0MA */ + +  lis     r28, 0xEEC0     /* address of PCIC0_CFGADDR */ +  addi    r29, r28, 4     /* add 4 to r29 -> PCIC0_CFGDATA */ + +  lis     r31, 0x8000     /* set en bit bus 0 */ +  ori     r31, r31, 0x304C/* device 6 func 0 reg 4C (XBCS register) */ +  stwbrx  r31, r0, r28    /* write it */ + +  lwbrx   r31, r0, r29    /* load XBCS register */ +  oris    r31, r31, 0x02C4/* clear BIOSCS WPE, set lower, extended and 1M extended BIOS enable */ +  stwbrx  r31, r0, r29    /* write back XBCS register */ + +  nop +  nop +  b	_start		/* normal start */ +#endif diff --git a/board/mpl/pip405/pip405.c b/board/mpl/pip405/pip405.c index a77e2c9ba..b4715aada 100644 --- a/board/mpl/pip405/pip405.c +++ b/board/mpl/pip405/pip405.c @@ -194,6 +194,11 @@ int board_pre_init (void)  #ifdef SDRAM_DEBUG  	DECLARE_GLOBAL_DATA_PTR;  #endif +	/* set up the config port */ +	mtdcr (ebccfga, pb7ap); +	mtdcr (ebccfgd, CONFIG_PORT_AP); +	mtdcr (ebccfga, pb7cr); +	mtdcr (ebccfgd, CONFIG_PORT_CR);  	memclk = get_bus_freq (tmemclk);  	tmemclk = 1000000000 / (memclk / 100);	/* in 10 ps units */ @@ -657,8 +662,20 @@ static int test_dram (unsigned long ramsize)  } +extern flash_info_t flash_info[];	/* info for FLASH chips */ +  int misc_init_r (void)  { +	DECLARE_GLOBAL_DATA_PTR; +	/* adjust flash start and size as well as the offset */ +	gd->bd->bi_flashstart=0-flash_info[0].size; +	gd->bd->bi_flashsize=flash_info[0].size-CFG_MONITOR_LEN; +	gd->bd->bi_flashoffset=0; + +	/* if PIP405 has booted from PCI, reset CCR0[24] as described in errata PCI_18 */ +	if (mfdcr(strap) & PSR_ROM_LOC) +	       mtspr(ccr0, (mfspr(ccr0) & ~0x80)); +  	return (0);  } diff --git a/board/mpl/pip405/pip405.h b/board/mpl/pip405/pip405.h index c2411a32e..b41c5bb28 100644 --- a/board/mpl/pip405/pip405.h +++ b/board/mpl/pip405/pip405.h @@ -25,6 +25,7 @@   * Global routines used for PIP405   *****************************************************************************/ +#ifndef __ASSEMBLY__  extern int  mem_test(unsigned long start, unsigned long ramsize,int mode); @@ -35,13 +36,13 @@ void user_led1(unsigned char on);  #define PLD_BASE_ADDRESS		CFG_ISA_IO_BASE_ADDRESS + 0x800 -#define PLD_PART_REG				PLD_BASE_ADDRESS + 0 -#define PLD_VERS_REG				PLD_BASE_ADDRESS + 1 +#define PLD_PART_REG			PLD_BASE_ADDRESS + 0 +#define PLD_VERS_REG			PLD_BASE_ADDRESS + 1  #define PLD_BOARD_CFG_REG		PLD_BASE_ADDRESS + 2  #define PLD_LED_USER_REG		PLD_BASE_ADDRESS + 3  #define PLD_SYS_MAN_REG			PLD_BASE_ADDRESS + 4  #define PLD_FLASH_COM_REG		PLD_BASE_ADDRESS + 5 -#define PLD_CAN_REG					PLD_BASE_ADDRESS + 6 +#define PLD_CAN_REG			PLD_BASE_ADDRESS + 6  #define PLD_SER_PWR_REG			PLD_BASE_ADDRESS + 7  #define PLD_COM_PWR_REG			PLD_BASE_ADDRESS + 8  #define PLD_NIC_VGA_REG			PLD_BASE_ADDRESS + 9 @@ -50,86 +51,32 @@ void user_led1(unsigned char on);  #define PIIX4_VENDOR_ID			0x8086  #define PIIX4_IDE_DEV_ID		0x7111 +#endif  /* timings */ -/* PLD (CS7) */ -#define PLD_BME	0 	/* Burst disable */ -#define PLD_TWE	5	/* 5 * 30ns 120ns Waitstates (access=TWT+1+TH) */ -#define PLD_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */ -#define PLD_OEN	1	/* Cycles from CS low to OE low   */ -#define PLD_WBN	1	/* Cycles from CS low to WE low   */ -#define PLD_WBF	1	/* Cycles from WE high to CS high */ -#define PLD_TH	2	/* Number of hold cycles after transfer */ -#define PLD_RE	0	/* Ready disabled */ -#define PLD_SOR	1	/* Sample on Ready disabled */ -#define PLD_BEM	0	/* Byte Write only active on Write cycles */ -#define PLD_PEN	0	/* Parity disable */ -#define PLD_AP 	((PLD_BME << 31) + (PLD_TWE << 23) + (PLD_CSN << 18) + (PLD_OEN << 16) + (PLD_WBN << 14) + \ -					(PLD_WBF << 12) + (PLD_TH << 9) + (PLD_RE << 8) + (PLD_SOR << 7) + (PLD_BEM << 6) + (PLD_PEN << 5)) - -/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ -#define PLD_BS	0	/* 1 MByte */ -/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ -#define PLD_BU	3	/* R/W */ -/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ -#define PLD_BW	0	/* 16Bit */ -#define PLD_CR	((PER_PLD_ADDR & 0xfff00000) + (PLD_BS << 17) + (PLD_BU << 15) + (PLD_BW << 13)) - -/* timings */ - -#define PER_BOARD_ADDR (PER_UART1_ADDR+(1024*1024)) -/* Dummy CS to get the board revision */ -#define BOARD_BME	0 	/* Burst disable */ -#define BOARD_TWE	255	/* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */ -#define BOARD_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */ -#define BOARD_OEN	1	/* Cycles from CS low to OE low   */ -#define BOARD_WBN	1	/* Cycles from CS low to WE low   */ -#define BOARD_WBF	1	/* Cycles from WE high to CS high */ -#define BOARD_TH	2	/* Number of hold cycles after transfer */ -#define BOARD_RE	0	/* Ready disabled */ -#define BOARD_SOR	1	/* Sample on Ready disabled */ -#define BOARD_BEM	0	/* Byte Write only active on Write cycles */ -#define BOARD_PEN	0	/* Parity disable */ -#define BOARD_AP 	((BOARD_BME << 31) + (BOARD_TWE << 23) + (BOARD_CSN << 18) + (BOARD_OEN << 16) + (BOARD_WBN << 14) + \ -					(BOARD_WBF << 12) + (BOARD_TH << 9) + (BOARD_RE << 8) + (BOARD_SOR << 7) + (BOARD_BEM << 6) + (BOARD_PEN << 5)) +/* CS Config register (CS7) */ +#define CONFIG_PORT_BME	0 	/* Burst disable */ +#define CONFIG_PORT_TWE	255	/* 255 * 30ns 120ns Waitstates (access=TWT+1+TH) */ +#define CONFIG_PORT_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */ +#define CONFIG_PORT_OEN	1	/* Cycles from CS low to OE low   */ +#define CONFIG_PORT_WBN	1	/* Cycles from CS low to WE low   */ +#define CONFIG_PORT_WBF	1	/* Cycles from WE high to CS high */ +#define CONFIG_PORT_TH	2	/* Number of hold cycles after transfer */ +#define CONFIG_PORT_RE	0	/* Ready disabled */ +#define CONFIG_PORT_SOR	1	/* Sample on Ready disabled */ +#define CONFIG_PORT_BEM	0	/* Byte Write only active on Write cycles */ +#define CONFIG_PORT_PEN	0	/* Parity disable */ +#define CONFIG_PORT_AP 	((CONFIG_PORT_BME << 31) + (CONFIG_PORT_TWE << 23) + (CONFIG_PORT_CSN << 18) + (CONFIG_PORT_OEN << 16) + (CONFIG_PORT_WBN << 14) + \ +				(CONFIG_PORT_WBF << 12) + (CONFIG_PORT_TH << 9) + (CONFIG_PORT_RE << 8) + (CONFIG_PORT_SOR << 7) + (CONFIG_PORT_BEM << 6) + (CONFIG_PORT_PEN << 5))  /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ -#define BOARD_BS	0	/* 1 MByte */ +#define CONFIG_PORT_BS	0	/* 1 MByte */  /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ -#define BOARD_BU	3	/* R/W */ +#define CONFIG_PORT_BU	3	/* R/W */  /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ -#define BOARD_BW	0	/* 16Bit */ -#define BOARD_CR	((PER_BOARD_ADDR & 0xfff00000) + (BOARD_BS << 17) + (BOARD_BU << 15) + (BOARD_BW << 13)) - - -/* UART0 CS2 */ -#define UART0_BME	0 	/* Burst disable */ -#define UART0_TWE	7	/* 7 * 30ns 210ns Waitstates (access=TWT+1+TH) */ -#define UART0_CSN	1	/* Chipselect is driven inactive for 1 Cycle BTW transfers */ -#define UART0_OEN	1	/* Cycles from CS low to OE low   */ -#define UART0_WBN	1	/* Cycles from CS low to WE low   */ -#define UART0_WBF	1	/* Cycles from WE high to CS high */ -#define UART0_TH	2	/* Number of hold cycles after transfer */ -#define UART0_RE	0	/* Ready disabled */ -#define UART0_SOR	1	/* Sample on Ready disabled */ -#define UART0_BEM	0	/* Byte Write only active on Write cycles */ -#define UART0_PEN	0	/* Parity disable */ -#define UART0_AP 	((UART0_BME << 31) + (UART0_TWE << 23) + (UART0_CSN << 18) + (UART0_OEN << 16) + (UART0_WBN << 14) + \ -					(UART0_WBF << 12) + (UART0_TH << 9) + (UART0_RE << 8) + (UART0_SOR << 7) + (UART0_BEM << 6) + (UART0_PEN << 5)) - -/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ -#define UART0_BS	0	/* 1 MByte */ -/* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */ -#define UART0_BU	3	/* R/W */ -/* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */ -#define UART0_BW	0	/* 8Bit */ -#define UART0_CR	((PER_UART0_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13)) - -/* UART1 CS3 */ -#define UART1_AP UART0_AP /* same timing as UART0 */ -#define UART1_CR	((PER_UART1_ADDR & 0xfff00000) + (UART0_BS << 17) + (UART0_BU << 15) + (UART0_BW << 13)) - +#define CONFIG_PORT_BW	0	/* 16Bit */ +#define CONFIG_PORT_CR	((CONFIG_PORT_ADDR & 0xfff00000) + (CONFIG_PORT_BS << 17) + (CONFIG_PORT_BU << 15) + (CONFIG_PORT_BW << 13))  /* Flash CS0 or CS 1 */  /* 0x7F8FFE80 slowest timing at all... */ @@ -149,19 +96,19 @@ void user_led1(unsigned char on);  #define FLASH_PEN	0	/* Parity disable */  /* Access Parameter Register for non Boot */  #define FLASH_AP 	((FLASH_BME << 31) + (FLASH_TWE << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \ -					(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5)) +				(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))  /* Access Parameter Register for Boot */  #define FLASH_AP_B 	((FLASH_BME_B << 31) + (FLASH_FWT_B << 26) + (FLASH_BWT_B << 23) + (FLASH_CSN << 18) + (FLASH_OEN << 16) + (FLASH_WBN << 14) + \ -					(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5)) +				(FLASH_WBF << 12) + (FLASH_TH << 9) + (FLASH_RE << 8) + (FLASH_SOR << 7) + (FLASH_BEM << 6) + (FLASH_PEN << 5))  /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ -#define FLASH_BS	2	/* 4 MByte */ +#define FLASH_BS	FLASH_SIZE_PRELIM	/* 4 MByte */  /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */  #define FLASH_BU	3	/* R/W */  /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */  #define FLASH_BW	1	/* 16Bit */  /* CR register for Boot */ -#define FLASH_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) +#define FLASH_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13))  /* CR register for non Boot */  #define FLASH_CR	((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (FLASH_BS << 17) + (FLASH_BU << 15) + (FLASH_BW << 13)) @@ -183,18 +130,19 @@ void user_led1(unsigned char on);  #define MPS_PEN		0	/* Parity disable */  /* Access Parameter Register for non Boot */  #define MPS_AP 		((MPS_BME << 31) + (MPS_TWE << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \ -					(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5)) +				(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))  /* Access Parameter Register for Boot */ -#define MPS_AP_B 		((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \ -					(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5)) +#define MPS_AP_B 	((MPS_BME_B << 31) + (MPS_FWT_B << 26) + (MPS_BWT_B << 23) + (MPS_CSN << 18) + (MPS_OEN << 16) + (MPS_WBN << 14) + \ +				(MPS_WBF << 12) + (MPS_TH << 9) + (MPS_RE << 8) + (MPS_SOR << 7) + (MPS_BEM << 6) + (MPS_PEN << 5))  /* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */  #define MPS_BS		2	/* 4 MByte */ +#define MPS_BS_B		FLASH_SIZE_PRELIM	/* 1 MByte */  /* Usage: 0=disabled, 1=Read only, 2=Write Only, 3=R/W */  #define MPS_BU		3	/* R/W */  /* Bus width: 0=8Bit, 1=16Bit, 2=32Bit, 3=Reserved */  #define MPS_BW		0	/* 8Bit */  /* CR register for Boot */ -#define MPS_CR_B	((FLASH_BASE0_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) +#define MPS_CR_B	((FLASH_BASE_PRELIM & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13))  /* CR register for non Boot */  #define MPS_CR		((MULTI_PURPOSE_SOCKET_ADDR & 0xfff00000) + (MPS_BS << 17) + (MPS_BU << 15) + (MPS_BW << 13)) diff --git a/board/sixnet/flash.c b/board/sixnet/flash.c index 225513acc..4ab6c1bdc 100644 --- a/board/sixnet/flash.c +++ b/board/sixnet/flash.c @@ -23,6 +23,10 @@  #include <common.h>  #include <mpc8xx.h> +/* environment.h defines the various CFG_ENV_... values in terms + * of whichever ones are given in the configuration file. + */ +#include <environment.h>  flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/ @@ -104,6 +108,19 @@ unsigned long flash_init (void)  		      &flash_info[0]);  #endif +#ifdef CFG_ENV_ADDR +	flash_protect ( FLAG_PROTECT_SET, +			CFG_ENV_ADDR, +			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); +#endif + +#ifdef CFG_ENV_ADDR_REDUND +	flash_protect ( FLAG_PROTECT_SET, +			CFG_ENV_ADDR_REDUND, +			CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1, +			&flash_info[0]); +#endif +  	return (size_b);  } @@ -154,6 +171,21 @@ static void flash_get_offsets (ulong base, flash_info_t *info)  		for( i = 0; i < info->sector_count; i++ )  			info->start[i] = base + (i * sect_size);  	} +	else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD +		 && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM800T) { + +		int sect_size;		/* number of bytes/sector */ + +		sect_size = 0x00010000 * (sizeof(FPW)/2); + +		/* set up sector start address table (top boot sector type) */ +		for (i = 0; i < info->sector_count - 3; i++) +			info->start[i] = base + (i * sect_size); +		i = info->sector_count - 1; +		info->start[i--] = base + (info->size - 0x00004000) * (sizeof(FPW)/2); +		info->start[i--] = base + (info->size - 0x00006000) * (sizeof(FPW)/2); +		info->start[i--] = base + (info->size - 0x00008000) * (sizeof(FPW)/2); +	}  }  /*----------------------------------------------------------------------- @@ -196,6 +228,9 @@ void flash_print_info (flash_info_t *info)  	}  	switch (info->flash_id & FLASH_TYPEMASK) { +	case FLASH_AM800T: +		fmt = "29LV800B%s (8 Mbit, %s)\n"; +		break;  	case FLASH_AM640U:  		fmt = "29LV641D (64 Mbit, uniform sectors)\n";  		break; @@ -295,6 +330,12 @@ ulong flash_get_size (FPWV *addr, flash_info_t *info)  	/* Check 16 bits or 32 bits of ID so work on 32 or 16 bit bus. */  	if (info->flash_id != FLASH_UNKNOWN) switch (addr[1]) { +	case (FPW)AMD_ID_LV800T: +		info->flash_id += FLASH_AM800T; +		info->sector_count = 19; +		info->size = 0x00100000 * (sizeof(FPW)/2); +		break;				/* => 1 or 2 MiB	*/ +  	case (FPW)AMD_ID_LV640U:	/* 29LV640 and 29LV641 have same ID */  		info->flash_id += FLASH_AM640U;  		info->sector_count = 128; @@ -401,6 +442,7 @@ static void flash_sync_real_protect(flash_info_t *info)  	break;      case FLASH_AM640U: +    case FLASH_AM800T:      default:  	/* no hardware protect that we support */  	break; @@ -438,6 +480,7 @@ int	flash_erase (flash_info_t *info, int s_first, int s_last)  	case FLASH_28F320C3B:  	case FLASH_28F640C3B:  	case FLASH_AM640U: +	case FLASH_AM800T:  		break;  	case FLASH_UNKNOWN:  	default: @@ -735,6 +778,7 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)  		break;  	case FLASH_AM640U: +	case FLASH_AM800T:  	default:  		/* no hardware protect that we support */  		info->protect[sector] = prot; diff --git a/board/sixnet/sixnet.c b/board/sixnet/sixnet.c index e33925c6f..4025b4789 100644 --- a/board/sixnet/sixnet.c +++ b/board/sixnet/sixnet.c @@ -24,6 +24,7 @@  #include <common.h>  #include <config.h> +#include <jffs2/jffs2.h>  #include <mpc8xx.h>  #include <net.h>	/* for eth_init() */  #include <rtc.h> @@ -602,3 +603,70 @@ long int initdram(int board_type)  	return (size_sdram);  } + +#ifdef CFG_JFFS_CUSTOM_PART + +static struct part_info part; + +#define jffs2_block(i)	\ +	((struct jffs2_unknown_node*)(CFG_JFFS2_BASE + (i) * 65536)) + +struct part_info* jffs2_part_info(int part_num) +{ +	DECLARE_GLOBAL_DATA_PTR; +	bd_t *bd = gd->bd; +	char* s; +	int i; +	int bootnor = 0;	/* assume booting from NAND flash */ + +	if (part_num != 0) +		return 0;	/* only support one partition */ + +	if (part.usr_priv == (void*)1) +		return ∂	/* already have part info */ + +	memset(&part, 0, sizeof(part)); + +	if (nand_dev_desc[0].ChipID == NAND_ChipID_UNKNOWN) +		bootnor = 1; +	else if (bd->bi_flashsize < 0x800000) +		bootnor = 0; +	else for (i = 0; !bootnor && i < 4; ++i) { +		/* boot from NOR if JFFS2 info in any of +		 * first 4 erase blocks +		 */ + +		if (jffs2_block(i)->magic == JFFS2_MAGIC_BITMASK) +			bootnor = 1; +	} + +	if (bootnor) { +		/* no NAND flash or boot in NOR, use NOR flash */ +		part.offset = (unsigned char *)CFG_JFFS2_BASE; +		part.size = CFG_JFFS2_SIZE; +	} +	else { +		char readcmd[60]; + +		/* boot info in NAND flash, get and use copy in RAM */ + +		/* override info from environment if present */ +		s = getenv("fsaddr"); +		part.offset = s ? (void *)simple_strtoul(s, NULL, 16) +				: (void *)CFG_JFFS2_RAMBASE; +		s = getenv("fssize"); +		part.size = s ? simple_strtoul(s, NULL, 16) +			      : CFG_JFFS2_RAMSIZE; + +		/* read from nand flash */ +		sprintf(readcmd, "nand read.jffs2 %x 0 %x", +			(uint32_t)part.offset, part.size); +		run_command(readcmd, 0); +	} + +	part.erasesize = 0;	/* unused */ +	part.usr_priv=(void*)1;	/* ready */ + +	return ∂ +} +#endif /* ifdef CFG_JFFS_CUSTOM_PART */ diff --git a/common/cmd_doc.c b/common/cmd_doc.c index 31862cf24..e5db1bc36 100644 --- a/common/cmd_doc.c +++ b/common/cmd_doc.c @@ -861,8 +861,13 @@ static int find_boot_record(struct NFTLrecord *nftl)  		memcpy(mh, buf, sizeof(struct NFTLMediaHeader));  		/* Do some sanity checks on it */ -		if (mh->UnitSizeFactor != 0xff) { -			puts ("Sorry, we don't support UnitSizeFactor " +		if (mh->UnitSizeFactor == 0) { +#ifdef NFTL_DEBUG +			puts ("UnitSizeFactor 0x00 detected.\n" +			      "This violates the spec but we think we know what it means...\n"); +#endif +		} else if (mh->UnitSizeFactor != 0xff) { +			printf ("Sorry, we don't support UnitSizeFactor "  			      "of != 1 yet.\n");  			return -1;  		} @@ -950,6 +955,8 @@ static void DoC2k_init(struct DiskOnChip* this)  	/* Ident all the chips present. */  	DoC_ScanChips(this); +	if ((!this->numchips) || (!this->chips)) +		return;  	nftl = &this->nftl; diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 27f832282..2a1da95b8 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -36,76 +36,179 @@  #include <fat.h> -extern block_dev_desc_t *ide_get_dev (int dev); + + + +block_dev_desc_t *get_dev (char* ifname, int dev) +{ +#if (CONFIG_COMMANDS & CFG_CMD_IDE) +	if (strncmp(ifname,"ide",3)==0) { +		extern block_dev_desc_t * ide_get_dev(int dev); +		return(ide_get_dev(dev)); +	} +#endif +#if (CONFIG_COMMANDS & CFG_CMD_SCSI) +	if (strncmp(ifname,"scsi",4)==0) { +		extern block_dev_desc_t * scsi_get_dev(int dev); +		return(scsi_get_dev(dev)); +	} +#endif +#if ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE)) +	if (strncmp(ifname,"usb",3)==0) { +		extern block_dev_desc_t * usb_stor_get_dev(int dev); +		return(usb_stor_get_dev(dev)); +	} +#endif +#if defined(CONFIG_MMC) +	if (strncmp(ifname,"mmc",3)==0) { +		extern block_dev_desc_t *  mmc_get_dev(int dev); +		return(mmc_get_dev(dev)); +	} +#endif +	return NULL; +} +  int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  {  	long size;  	unsigned long offset;  	unsigned long count; +	block_dev_desc_t *dev_desc=NULL; +	int dev=0; +	int part=1; +	char *ep; -	if (argc < 3) { -		printf ("usage:fatload <filename> <addr> [bytes]\n"); +	if (argc < 5) { +		printf ("usage: fatload <interface> <dev[:part]> <addr> <filename> [bytes]\n");  		return (0);  	} - -	offset = simple_strtoul (argv[2], NULL, 16); -	if (argc == 4) -		count = simple_strtoul (argv[3], NULL, 16); +	dev = (int)simple_strtoul (argv[2], &ep, 16); +	dev_desc=get_dev(argv[1],dev); +	if (dev_desc==NULL) { +		puts ("\n** Invalid boot device **\n"); +		return 1; +	} +	if (*ep) { +		if (*ep != ':') { +			puts ("\n** Invalid boot device, use `dev[:part]' **\n"); +			return 1; +		} +		part = (int)simple_strtoul(++ep, NULL, 16); +	} +	if (fat_register_device(dev_desc,part)!=0) { +		printf ("\n** Unable to use %s %d:%d for fatload **\n",argv[1],dev,part); +		return 1; +	} +	offset = simple_strtoul (argv[3], NULL, 16); +	if (argc == 6) +		count = simple_strtoul (argv[5], NULL, 16);  	else  		count = 0; +	size = file_fat_read (argv[4], (unsigned char *) offset, count); -	size = file_fat_read (argv[1], (unsigned char *) offset, count); - -	printf ("%ld bytes read\n", size); +	if(size==-1) +		printf("\n** Unable to read \"%s\" from %s %d:%d **\n",argv[4],argv[1],dev,part); +	else +		printf ("\n%ld bytes read\n", size);  	return size;  } + + +  U_BOOT_CMD( -	fatload,	4,	0,	do_fat_fsload, +	fatload,	6,	0,	do_fat_fsload,  	"fatload - load binary file from a dos filesystem\n", -	"[ off ] [ filename ]\n" -	"    - load binary file from dos filesystem\n" -	"      with offset 'off'\n" +	"<interface> <dev[:part]>  <addr> <filename> [bytes]\n" +	"    - load binary file 'filename' from 'dev' on 'interface'\n" +	"      to address 'addr' from dos filesystem\n"  );  int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  {  	char *filename = "/";  	int ret; +	int dev=0; +	int part=1; +	char *ep; +	block_dev_desc_t *dev_desc=NULL; -	if (argc == 2) -		ret = file_fat_ls (argv[1]); +	if (argc < 3) { +		printf ("usage: fatls <interface> <dev[:part]> [directory]\n"); +		return (0); +	} +	dev = (int)simple_strtoul (argv[2], &ep, 16); +	dev_desc=get_dev(argv[1],dev); +	if (dev_desc==NULL) { +		puts ("\n** Invalid boot device **\n"); +		return 1; +	} +	if (*ep) { +		if (*ep != ':') { +			puts ("\n** Invalid boot device, use `dev[:part]' **\n"); +			return 1; +		} +		part = (int)simple_strtoul(++ep, NULL, 16); +	} +	if (fat_register_device(dev_desc,part)!=0) { +		printf ("\n** Unable to use %s %d:%d for fatls **\n",argv[1],dev,part); +		return 1; +	} +	if (argc == 4) +		ret = file_fat_ls (argv[3]);  	else  		ret = file_fat_ls (filename); +	if(ret!=0) +		printf("No Fat FS detected\n");  	return (ret);  }  U_BOOT_CMD( -	fatls,	2,	1,	do_fat_ls, +	fatls,	4,	1,	do_fat_ls,  	"fatls   - list files in a directory (default /)\n", -	"[ directory ]\n" -	"    - list files in a directory\n" +	"<interface> <dev[:part]> [directory]\n" +	"    - list files from 'dev' on 'interface' in a 'directory'\n"  );  int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  { -	int ret; +	int dev=0; +	int part=1; +	char *ep; +	block_dev_desc_t *dev_desc=NULL; -	ret = 0; - -	printf ("FAT info: %d\n", file_fat_detectfs ()); - -	return (ret); +	if (argc < 2) { +		printf ("usage: fatinfo <interface> <dev[:part]>\n"); +		return (0); +	} +	dev = (int)simple_strtoul (argv[2], &ep, 16); +	dev_desc=get_dev(argv[1],dev); +	if (dev_desc==NULL) { +		puts ("\n** Invalid boot device **\n"); +		return 1; +	} +	if (*ep) { +		if (*ep != ':') { +			puts ("\n** Invalid boot device, use `dev[:part]' **\n"); +			return 1; +		} +		part = (int)simple_strtoul(++ep, NULL, 16); +	} +	if (fat_register_device(dev_desc,part)!=0) { +		printf ("\n** Unable to use %s %d:%d for fatinfo **\n",argv[1],dev,part); +		return 1; +	} +	return (file_fat_detectfs ());  }  U_BOOT_CMD( -	fatinfo,	1,	1,	do_fat_fsinfo, +	fatinfo,	3,	1,	do_fat_fsinfo,  	"fatinfo - print information about filesystem\n", -	"\n" -	"    - print information about filesystem\n" +	"<interface> <dev[:part]>\n" +	"    - print information about filesystem from 'dev' on 'interface'\n"  );  #ifdef NOT_IMPLEMENTED_YET diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c index f5915656f..3301bd97e 100644 --- a/common/cmd_jffs2.c +++ b/common/cmd_jffs2.c @@ -174,7 +174,7 @@ do_jffs2_chpart(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	}  	if (jffs2_part_info(tmp_part)){ -		printf("Partiton changed to %d\n",tmp_part); +		printf("Partition changed to %d\n",tmp_part);  		part_num=tmp_part;  		return 0;  	} diff --git a/cpu/mpc824x/Makefile b/cpu/mpc824x/Makefile index 3c00fc734..df0d64e41 100644 --- a/cpu/mpc824x/Makefile +++ b/cpu/mpc824x/Makefile @@ -25,14 +25,14 @@ include $(TOPDIR)/config.mk  LIB	= lib$(CPU).a -START	= start.S drivers/i2c/i2c2.o +START	= start.S  OBJS	= traps.o cpu.o cpu_init.o interrupts.o speed.o \ -	  drivers/epic/epic1.o drivers/i2c/i2c1.o pci.o bedbug_603e.o +	  drivers/epic/epic1.o drivers/i2c/i2c.o pci.o bedbug_603e.o  all:	.depend $(START) $(LIB)  $(LIB):	$(OBJS) -	$(AR) crv $@ $(OBJS) drivers/i2c/i2c2.o +	$(AR) crv $@ $(OBJS)  bedbug_603e.c:  	ln -s ../mpc8260/bedbug_603e.c bedbug_603e.c diff --git a/cpu/mpc824x/drivers/i2c/Makefile b/cpu/mpc824x/drivers/i2c/Makefile deleted file mode 100644 index ae1a94c53..000000000 --- a/cpu/mpc824x/drivers/i2c/Makefile +++ /dev/null @@ -1,84 +0,0 @@ -########################################################################## -# -#       Copyright Motorola, Inc. 1997 -#       ALL RIGHTS RESERVED -# -#       You are hereby granted a copyright license to use, modify, and -#       distribute the SOFTWARE so long as this entire notice is retained -#       without alteration in any modified and/or redistributed versions, -#       and that such modified versions are clearly identified as such. -#       No licenses are granted by implication, estoppel or otherwise under -#       any patents or trademarks of Motorola, Inc. -# -#       The SOFTWARE is provided on an "AS IS" basis and without warranty. -#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS -#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED -#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR -#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH -#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS -#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS. -# -#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL -#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER -#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF -#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS -#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR -#       INABILITY TO USE THE SOFTWARE. -# -############################################################################ -TARGET = libi2c.a - -#DEBUG  = -g -DEBUG   = -DI2CDBG -LST     = -Hanno -S -OPTIM   = -CC      = /risc/tools/pkgs/metaware/bin/hcppc -CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc -CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM) -PREP    = $(CC) $(CFLAGS) -P - -# Assembler used to build the .s files (for the board version) - -ASOPT   = -big_si -c -ASDEBUG = -l -fm -AS      = /risc/tools/pkgs/metaware/bin/asppc - -# Linker to bring .o files together into an executable. - -LKOPT	=  -Bbase=0 -q -Qn -r -LKCMD   = -LINK    =  /risc/tools/pkgs/metaware/bin/ldppc $(LKCMD) $(LKOPT) - -# DOS Utilities - -DEL     = rm -COPY    = cp -LIST    = ls - -OBJECTS = i2c1.o i2c2.o - -all: $(TARGET) - -objects: $(OBJECTS) - -$(TARGET): $(OBJECTS) -	$(LINK) $(OBJECTS) -o $@ - -clean: -	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS) - -.s.o: -	$(DEL) -f $*.i -	$(PREP) -Hasmcpp $< -	$(AS) $(ASOPT) $*.i -#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst - -.c.o: -	$(CCobj) $< - -.c.s: -	$(CCobj) $(LST) $< - -i2c1.o: i2c_export.h i2c.h i2c1.c - -i2c2.o: i2c.h i2c2.s diff --git a/cpu/mpc824x/drivers/i2c/Makefile_pc b/cpu/mpc824x/drivers/i2c/Makefile_pc deleted file mode 100644 index 4d42c7b84..000000000 --- a/cpu/mpc824x/drivers/i2c/Makefile_pc +++ /dev/null @@ -1,91 +0,0 @@ -########################################################################## -# -#       makefile_pc for use with PC mksnt tools  dink32/drivers/i2c -# -#       Copyright Motorola, Inc. 1997 -#       ALL RIGHTS RESERVED -# -#       You are hereby granted a copyright license to use, modify, and -#       distribute the SOFTWARE so long as this entire notice is retained -#       without alteration in any modified and/or redistributed versions, -#       and that such modified versions are clearly identified as such. -#       No licenses are granted by implication, estoppel or otherwise under -#       any patents or trademarks of Motorola, Inc. -# -#       The SOFTWARE is provided on an "AS IS" basis and without warranty. -#       To the maximum extent permitted by applicable law, MOTOROLA DISCLAIMS -#       ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING IMPLIED -#       WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR -#       PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH -#       REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS -#       THEREOF) AND ANY ACCOMPANYING WRITTEN MATERIALS. -# -#       To the maximum extent permitted by applicable law, IN NO EVENT SHALL -#       MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER -#       (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF -#       BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS -#       INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OF THE USE OR -#       INABILITY TO USE THE SOFTWARE. -# -############################################################################ -TARGET = libi2c.a - -#DEBUG  = -g -DEBUG   = -DI2CDBG -LST     = -Hanno -S -OPTIM   = -CC      = m:/old_tools/tools/hcppc/bin/hcppc -CFLAGS  = -Hnocopyr -c -Hsds -Hon=Char_default_unsigned -Hon=Char_is_rep -I../inc -I/risc/tools/pkgs/metaware/inc -CCobj   = $(CC) $(CFLAGS) $(DEBUG) $(OPTIM) -PREP    = $(CC) $(CFLAGS) -P - -# Assembler used to build the .s files (for the board version) - -ASOPT   = -big_si -c -ASDEBUG = -l -fm -AS      = m:/old_tools/tools/hcppc/bin/asppc - -# Linker to bring .o files together into an executable. - -LKOPT	=  -Bbase=0 -q -Qn -r -LKCMD   = -LINK    = m:/old_tools/tools/hcppc/bin/ldppc $(LKCMD) $(LKOPT) - -# DOS Utilities - -DEL     = rm -COPY    = cp -LIST    = ls - -OBJECTS = i2c1.o i2c2.o - -all: $(TARGET) - -objects: $(OBJECTS) - -$(TARGET): $(OBJECTS) -	$(LINK) $(OBJECTS) -o $@ - -clean: -	$(DEL) -f *.o *.i *.map *.lst $(TARGET) $(OBJECTS) - -.s.o: -	$(DEL) -f $*.i -	$(PREP) -Hasmcpp $< -	$(AS) $(ASOPT) $*.i -#	$(AS) $(ASOPT) $(ASDEBUG) $*.i > $*.lst - -.c.o: -	$(CCobj) $< - -.c.s: -	$(CCobj) $(LST) $< - -i2c1.o: i2c_export.h i2c.h i2c1.c -	$(CCobj) $< - - -i2c2.o: i2c.h i2c2.s -	$(DEL) -f $*.i -	$(PREP) -Hasmcpp $< -	$(AS) $(ASOPT) $*.i diff --git a/cpu/mpc824x/drivers/i2c/README b/cpu/mpc824x/drivers/i2c/README deleted file mode 100644 index 1db72108c..000000000 --- a/cpu/mpc824x/drivers/i2c/README +++ /dev/null @@ -1,104 +0,0 @@ -CONTENT: - -   i2c.h -   i2c1.c -   i2c2.s - -WHAT ARE THESE FILES: - -These files contain MPC8240 (Kahlua) I2C -driver routines. The driver routines are not -written for any specific operating system. -They serves the purpose of code sample, and -jump-start for using the MPC8240 I2C unit. - -For the reason of correctness of C language -syntax, these files are compiled by Metaware -C compiler and assembler. - -ENDIAN NOTATION: - -The algorithm is designed for big-endian mode, -software is responsible for byte swapping. - -USAGE: - -1. The host system that is running on MPC8240 -   shall link the files listed here. The memory -   location of driver routines shall take into -   account of that driver routines need to run -   in supervisor mode and they process I2C -   interrupt. - -2. The host system is responsible for configuring -   the MPC8240 including Embedded Utilities Memory -   Block. All I2C driver functions require the -   content of Embedded Utilities Memory Block -   Base Address Register, EUMBBAR, as the first -   parameter. - -3. Before I2C unit of MPC8240 can be used, -   initialize I2C unit by calling I2C_Init -   with the corresponding parameters. - -   Note that the I2CFDR register shall be written -   once during the initialization. If it is written -   in the midst of transers, or after I2C STOPs or -   REPEAT STATRs, depending on the data written, -   a long reset time may be encountered. - -4. After I2C unit has been successfully initialized, -   use the Application level API to send data or -   receive data upon the desired mode, Master or -   Slave. - -5. If the host system is also using the EPIC unit -   on MPC8240, the system can register the -   I2C_ISR with the EPIC including other -   desired resources. - -   If the host system does not using the EPIC unit -   on MPC8240, I2C_Timer_Event function can -   be called for each desired time interval. - -   In both cases, the host system is free to provide -   its own timer event handler and interrupt service -   routine. - -6. The I2C driver routines contains a set -   of utilities, Set and Get, for host system -   to query and modify the desired I2C registers. - -7. It is the host system's responsibility of -   queueing the I2C I/O request. The host -   system shall check the I2C_ISR return code -   for I2C I/O status. If I2C_ISR returns -   I2CBUFFEMPTY or I2CBUFFFULL, it means -   I2C unit has completed a I/O request -   stated by the Application API. - -8. If the host system has more than one master -   mode I2C unit I/O requests but doesn't want -   to be intervented by being addressed as slave, -   the host system can use the master mode -   Application API with stop_flag set to 0 in -   conjunction with is_cnt flag set to 1. -   The first API call sets both stop_flag and -   is_cnt to 0, indicating a START condition -   shall be generated but when the end of -   transaction is reached, do not generate a -   STOP condition. Once the host system is -   informed that the transaction has been -   completed, the next Application API call -   shall set is_cnt flag to 1, indicating a -   repeated START condition shall be generated. -   The last Application API call shall set -   stop_flag -   to 1. - -9. The I2C_Timer_Event function containes -   a user defined function pointer. It -   serves the purpose of providing the -   host system a way to use its own event -   handler instead of the I2C_ISR provided -   here. diff --git a/cpu/mpc824x/drivers/i2c/i2c.c b/cpu/mpc824x/drivers/i2c/i2c.c new file mode 100644 index 000000000..7445a1ce3 --- /dev/null +++ b/cpu/mpc824x/drivers/i2c/i2c.c @@ -0,0 +1,284 @@ +/* + * (C) Copyright 2003 + * Gleb Natapov <gnatapov@mrv.com> + * Some bits are taken from linux driver writen by adrian@humboldt.co.uk + * + * Hardware I2C driver for MPC107 PCI bridge. + * + * 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> + +#undef I2CDBG + +#ifdef CONFIG_HARD_I2C +#include <i2c.h> + +#define TIMEOUT (CFG_HZ/4) + +#define I2C_Addr ((unsigned *)(CFG_EUMB_ADDR + 0x3000)) + +#define I2CADR &I2C_Addr[0] +#define I2CFDR  &I2C_Addr[1] +#define I2CCCR  &I2C_Addr[2] +#define I2CCSR  &I2C_Addr[3] +#define I2CCDR  &I2C_Addr[4] + +#define MPC107_CCR_MEN  0x80 +#define MPC107_CCR_MIEN 0x40 +#define MPC107_CCR_MSTA 0x20 +#define MPC107_CCR_MTX  0x10 +#define MPC107_CCR_TXAK 0x08 +#define MPC107_CCR_RSTA 0x04 + +#define MPC107_CSR_MCF  0x80 +#define MPC107_CSR_MAAS 0x40 +#define MPC107_CSR_MBB  0x20 +#define MPC107_CSR_MAL  0x10 +#define MPC107_CSR_SRW  0x04 +#define MPC107_CSR_MIF  0x02 +#define MPC107_CSR_RXAK 0x01 + +#define I2C_READ  1 +#define I2C_WRITE 0 + +/* taken from linux include/asm-ppc/io.h */ +inline unsigned in_le32 (volatile unsigned *addr) +{ +	unsigned ret; + +	__asm__ __volatile__ ("lwbrx %0,0,%1;\n" +			      "twi 0,%0,0;\n" +			      "isync":"=r" (ret): "r" (addr), "m" (*addr)); +	return ret; +} + +inline void out_le32 (volatile unsigned *addr, int val) +{ +	__asm__ __volatile__ ("stwbrx %1,0,%2; eieio":"=m" (*addr):"r" (val), +			      "r" (addr)); +} + +#define writel(val, addr) out_le32(addr, val) +#define readl(addr) in_le32(addr) + +void i2c_init (int speed, int slaveadd) +{ +	/* stop I2C controller */ +	writel (0x0, I2CCCR); +	/* set clock */ +	writel (0x1020, I2CFDR); +	/* write slave address */ +	writel (slaveadd, I2CADR); +	/* clear status register */ +	writel (0x0, I2CCSR); +	/* start I2C controller */ +	writel (MPC107_CCR_MEN, I2CCCR); + +	return; +} + +static __inline__ int i2c_wait4bus (void) +{ +	ulong timeval = get_timer (0); + +	while (readl (I2CCSR) & MPC107_CSR_MBB) +		if (get_timer (timeval) > TIMEOUT) +			return -1; + +	return 0; +} + +static __inline__ int i2c_wait (int write) +{ +	u32 csr; +	ulong timeval = get_timer (0); + +	do { +		csr = readl (I2CCSR); + +		if (!(csr & MPC107_CSR_MIF)) +			continue; + +		writel (0x0, I2CCSR); + +		if (csr & MPC107_CSR_MAL) { +#ifdef I2CDBG +			printf ("i2c_wait: MAL\n"); +#endif +			return -1; +		} + +		if (!(csr & MPC107_CSR_MCF)) { +#ifdef I2CDBG +			printf ("i2c_wait: unfinished\n"); +#endif +			return -1; +		} + +		if (write == I2C_WRITE && (csr & MPC107_CSR_RXAK)) { +#ifdef I2CDBG +			printf ("i2c_wait: No RXACK\n"); +#endif +			return -1; +		} + +		return 0; +	} while (get_timer (timeval) < TIMEOUT); + +#ifdef I2CDBG +	printf ("i2c_wait: timed out\n"); +#endif +	return -1; +} + +static __inline__ int i2c_write_addr (u8 dev, u8 dir, int rsta) +{ +	writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX | +		(rsta ? MPC107_CCR_RSTA : 0), I2CCCR); + +	writel ((dev << 1) | dir, I2CCDR); + +	if (i2c_wait (I2C_WRITE) < 0) +		return 0; + +	return 1; +} + +static __inline__ int __i2c_write (u8 * data, int length) +{ +	int i; + +	writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | MPC107_CCR_MTX, I2CCCR); + +	for (i = 0; i < length; i++) { +		writel (data[i], I2CCDR); + +		if (i2c_wait (I2C_WRITE) < 0) +			break; +	} + +	return i; +} + +static __inline__ int __i2c_read (u8 * data, int length) +{ +	int i; + +	writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | +		((length == 1) ? MPC107_CCR_TXAK : 0), I2CCCR); + +	/* dummy read */ +	readl (I2CCDR); + +	for (i = 0; i < length; i++) { +		if (i2c_wait (I2C_READ) < 0) +			break; + +		/* Generate ack on last next to last byte */ +		if (i == length - 2) +			writel (MPC107_CCR_MEN | MPC107_CCR_MSTA | +				MPC107_CCR_TXAK, I2CCCR); + +		/* Generate stop on last byte */ +		if (i == length - 1) +			writel (MPC107_CCR_MEN | MPC107_CCR_TXAK, I2CCCR); + +		data[i] = readl (I2CCDR); +	} + +	return i; +} + +int i2c_read (u8 dev, uint addr, int alen, u8 * data, int length) +{ +	int i = 0; +	u8 *a = (u8 *) & addr; + +	if (i2c_wait4bus () < 0) +		goto exit; + +	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0) +		goto exit; + +	if (__i2c_write (&a[4 - alen], alen) != alen) +		goto exit; + +	if (i2c_write_addr (dev, I2C_READ, 1) == 0) +		goto exit; + +	i = __i2c_read (data, length); + +exit: +	writel (MPC107_CCR_MEN, I2CCCR); + +	return !(i == length); +} + +int i2c_write (u8 dev, uint addr, int alen, u8 * data, int length) +{ +	int i = 0; +	u8 *a = (u8 *) & addr; + +	if (i2c_wait4bus () < 0) +		goto exit; + +	if (i2c_write_addr (dev, I2C_WRITE, 0) == 0) +		goto exit; + +	if (__i2c_write (&a[4 - alen], alen) != alen) +		goto exit; + +	i = __i2c_write (data, length); + +exit: +	writel (MPC107_CCR_MEN, I2CCCR); + +	return !(i == length); +} + +int i2c_probe (uchar chip) +{ +	int tmp; + +	/* +	 * Try to read the first location of the chip.  The underlying +	 * driver doesn't appear to support sending just the chip address +	 * and looking for an <ACK> back. +	 */ +	udelay (10000); +	return i2c_read (chip, 0, 1, (char *) &tmp, 1); +} + +uchar i2c_reg_read (uchar i2c_addr, uchar reg) +{ +	char buf[1]; + +	i2c_read (i2c_addr, reg, 1, buf, 1); + +	return (buf[0]); +} + +void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val) +{ +	i2c_write (i2c_addr, reg, 1, &val, 1); +} + +#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc824x/drivers/i2c/i2c.h b/cpu/mpc824x/drivers/i2c/i2c.h deleted file mode 100644 index 48a401d90..000000000 --- a/cpu/mpc824x/drivers/i2c/i2c.h +++ /dev/null @@ -1,309 +0,0 @@ -#ifndef I2C_H -#define I2C_H - -/**************************************************** - * - * Copyright Motrola 1999 - * - ****************************************************/ -#define get_eumbbar() CFG_EUMB_ADDR - -#define I2CADR    0x00003000 -#define I2CFDR    0x00003004 -#define I2CCR     0x00003008 -#define I2CSR     0x0000300C -#define I2CDR     0x00003010 - -typedef enum _i2cstatus -{ - I2CSUCCESS     = 0x3000, - I2CADDRESS, - I2CERROR, - I2CBUFFFULL, - I2CBUFFEMPTY, - I2CXMITERROR, - I2CRCVERROR, - I2CBUSBUSY, - I2CALOSS, - I2CNOEVENT, -} I2CStatus; - -typedef enum i2c_control -{ - MEN  = 0x00000080, - MIEN = 0x00000040, - MSTA = 0x00000020, - MTX  = 0x00000010, - TXAK = 0x00000008, - RSTA = 0x00000004, -} I2C_CONTROL; - -typedef enum i2c_status -{ -  MCF   =  0x00000080, -  MAAS  =  0x00000040, -  MBB   =  0x00000020, -  MAL   =  0x00000010, -  SRW   =  0x00000004, -  MIF   =  0x00000002, -  RXAK  =  0x00000001, -} I2C_STATUS; - -typedef struct _i2c_ctrl -{ -	unsigned int reserved0 : 24; -	unsigned int men       : 1; -	unsigned int mien      : 1; -	unsigned int msta      : 1; -	unsigned int mtx       : 1; -	unsigned int txak      : 1; -	unsigned int rsta      : 1; -	unsigned int reserved1 : 2; -} I2C_CTRL; - -typedef struct _i2c_stat -{ -	unsigned int rsrv0    : 24; -	unsigned int mcf      : 1; -	unsigned int maas     : 1; -	unsigned int mbb      : 1; -	unsigned int mal      : 1; -	unsigned int rsrv1    : 1; -	unsigned int srw      : 1; -	unsigned int mif      : 1; -	unsigned int rxak     : 1; -} I2C_STAT; - -typedef enum _i2c_mode -{ -	RCV =  0, -	XMIT = 1, -} I2C_MODE; - -/******************** App. API ******************** - * The application API is for user level application - * to use the funcitonality provided by I2C driver - * - * Note: Its App.s responsibility to swap the data - *       byte. In our API, we just transfer whatever - *       we are given - **************************************************/ -/** - * Note: - * - * In all following functions, - * the caller shall pass the configured embedded utility memory - * block base, EUMBBAR. - **/ - -/* Send a buffer of data to the intended rcv_addr. - * If stop_flag is set, after the whole buffer - * is sent, generate a STOP signal provided that the - * receiver doesn't signal the STOP in the middle. - * I2C is the master performing transmitting. If - * no STOP signal is generated at the end of current - * transaction, the master can generate a START signal - * to another slave addr. - * - * return I2CSUCCESS if no error. - */ -static I2CStatus I2C_put( unsigned int  eumbbar, -						  unsigned char rcv_addr,    /* receiver's address */ -			      unsigned char *buffer_ptr, /* pointer of data to be sent */ -					      unsigned int  length,      /* number of byte of in the buffer */ -					      unsigned int  stop_flag,   /* 1 - signal STOP when buffer is empty -									  * 0 - no STOP signal when buffer is empty -												  */ -						  unsigned int  is_cnt );    /* 1 - this is a restart, don't check MBB -						      * 0 - this is a new start, check MBB -													  */ - -/* Receive a buffer of data from the desired sender_addr - * If stop_flag is set, when the buffer is full and the - * sender does not signal STOP, generate a STOP signal. - * I2C is the master performing receiving. If no STOP signal - * is generated, the master can generate a START signal - * to another slave addr. - * - * return I2CSUCCESS if no error. - */ -static I2CStatus I2C_get( unsigned int  eumbbar, -						  unsigned char sender_addr, /* sender's address */ -					      unsigned char *buffer_ptr, /* pointer of receiving buffer */ -					  unsigned int  length,      /* length of the receiving buffer */ -					      unsigned int  stop_flag,   /* 1 - signal STOP when buffer is full -									  * 0 - no STOP signal when buffer is full -												      */ -						  unsigned int  is_cnt );    /* 1 - this is a restart, don't check MBB -						      * 0 - this is a new start, check MBB -													  */ - -#if 0 /* the I2C_write and I2C_read functions are not active */ -/* Send a buffer of data to the requiring master. - * If stop_flag is set, after the whole buffer is sent, - * generate a STOP signal provided that the requiring - * receiver doesn't signal the STOP in the middle. - * I2C is the slave performing transmitting. - * - * return I2CSUCCESS if no error. - * - * Note: due to the Kahlua design, slave transmitter - *       shall not signal STOP since there is no way - *       for master to detect it, causing I2C bus hung. - * - *       For the above reason, the stop_flag is always - *       set, i.e., 1. - * - *       programmer shall use the timer on Kahlua to - *       control the interval of data byte at the - *       master side. - */ -static I2CStatus I2C_write( unsigned int eumbbar, -						    unsigned char *buffer_ptr, /* pointer of data to be sent */ -						unsigned int  length,      /* number of byte of in the buffer */ -						unsigned int  stop_flag ); /* 1 - signal STOP when buffer is empty -											* 0 - no STOP signal when buffer is empty -												    */ - - /* Receive a buffer of data from the sending master. - * If stop_flag is set, when the buffer is full and the - * sender does not signal STOP, generate a STOP signal. - * I2C is the slave performing receiving. - * - * return I2CSUCCESS if no error. - */ -static I2CStatus I2C_read(unsigned int  eumbbar, -						  unsigned char *buffer_ptr, /* pointer of receiving buffer */ -					      unsigned int  length,      /* length of the receiving buffer */ -					  unsigned int  stop_flag ); /* 1 - signal STOP when buffer is full -									  * 0 - no STOP signal when buffer is full -												      */ -#endif /* of if0 for turning off I2C_read & I2C_write */ - -/* if interrupt is not used, this is the timer event handler. - * After each fixed time interval, this function can be called - * to check the I2C status and call appropriate function to - * handle the status event. - */ -static I2CStatus I2C_Timer_Event( unsigned int eumbbar, I2CStatus (*handler)( unsigned int ) ); - -/********************* Kernel API ************************ - * Kernel APIs are functions I2C driver provides to the - * O.S. - *********************************************************/ - -/******************* device I/O function ***************/ - -/*  Generate a START signal in the desired mode. - *  I2C is the master. - * - * return I2CSUCCESS if no error. - *        I2CERROR   if i2c unit is not enabled. - *        I2CBUSBUSY if bus cannot be granted - */ -static I2CStatus I2C_Start( unsigned int  eumbbar, -						    unsigned char slave_addr, /* address of the receiver */ -				I2C_MODE     mode,       /* XMIT(1) - put (write) -										  * RCV(0)  - get (read) -													  */ -						    unsigned int is_cnt ); /* 1 - this is a restart, don't check MBB -													* 0 - this is a new start, check MBB -						    */ - -/* Generate a STOP signal to terminate the transaction. */ -static I2CStatus I2C_Stop( unsigned int eumbbar ); - -/*  Do a one-byte master transmit. - * - *  return I2CBUFFEMPTY if this is the last byte. - *  Otherwise return I2CSUCCESS - */ -static I2CStatus I2C_Master_Xmit( unsigned int eumbbar ); - -/*  Do a one-byte master receive. - * - *  return I2CBUFFFULL if this is the last byte. - *  Otherwise return I2CSUCCESS - */ -static I2CStatus I2C_Master_Rcv( unsigned int eumbbar ); - -/*  Do a one-byte slave transmit. - * - *  return I2CBUFFEMPTY if this is the last byte. - *  Otherwise return I2CSUCCESS - * - */ -static I2CStatus I2C_Slave_Xmit( unsigned int eumbbar ); - -/* Do a one-byte slave receive. - * - *  return I2CBUFFFULL if this is the last byte. - *  Otherwise return I2CSUCCESS - */ -static I2CStatus I2C_Slave_Rcv( unsigned int eumbbar  ); - -/* Process slave address phase. - * - * return I2CADDRESS if this is slave receiver's address phase - * Otherwise return the result of slave xmit one byte. - */ -static I2CStatus I2C_Slave_Addr( unsigned int eumbbar ); - -/******************* Device Control Fucntion ****************/ -/*  Initialize I2C unit with desired frequency divider, - *  driver's slave address w/o interrupt enabled. - * - *  This function must be called before I2C unit can - *  be used. - */ -static I2CStatus I2C_Init( unsigned int  eumbbar, -						   unsigned char fdr,       /* frequency divider */ -			       unsigned char addr,      /* driver's address used for receiving */ -					   unsigned int en_int);    /* 1 - enable I2C interrupt -									 * 0 - disable I2C interrup -												 */ - -/* I2C interrupt service routine. - * - * return I2CADDRESS if it is receiver's (either master or slave) address phase. - * return the result of xmit or receive one byte - */ -static I2CStatus I2C_ISR(unsigned int eumbbar  ); - -/* Set I2C Status, i.e., write to I2CSR */ -static void I2C_Set_Stat( unsigned int eumbbar, I2C_STAT stat ); - -/* Query I2C Status, i.e., read I2CSR */ -static I2C_STAT I2C_Get_Stat( unsigned int eumbbar ); - -/* Change I2C Control bits, i.e., write to I2CCR */ -static void I2C_Set_Ctrl( unsigned int eumbbar, I2C_CTRL ); /* new control value */ - -/* Query I2C Control bits, i.e., read I2CCR */ -static I2C_CTRL I2C_Get_Ctrl( unsigned int eumbbar ); - -/* This function performs the work for I2C_do_transaction.  The work is - * split into this function to enable I2C_do_transaction to first transmit - * the data address to the I2C slave device without putting the data address - * into the first byte of the buffer. - * - * en_int controls interrupt/polling mode - * act is the type of transaction - * i2c_addr is the I2C address of the slave device - * len is the length of data to send or receive - * buffer is the address of the data buffer - * stop = I2C_NO_STOP, don't signal STOP at end of transaction - *        I2C_STOP, signal STOP at end of transaction - * retry is the timeout retry value, currently ignored - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction - *        I2C_RESTART, this is a continuation of existing transaction - */ -static I2C_Status I2C_do_buffer( I2C_INTERRUPT_MODE en_int, -				 I2C_TRANSACTION_MODE act, -				 unsigned char i2c_addr, -				 int len, -				 unsigned char *buffer, -				 I2C_STOP_MODE stop, -				 int retry, -				 I2C_RESTART_MODE rsta); -#endif diff --git a/cpu/mpc824x/drivers/i2c/i2c1.c b/cpu/mpc824x/drivers/i2c/i2c1.c deleted file mode 100644 index 94c671e56..000000000 --- a/cpu/mpc824x/drivers/i2c/i2c1.c +++ /dev/null @@ -1,1243 +0,0 @@ -/************************************************************* - * - * Copyright @ Motorola, 1999 - * - ************************************************************/ -#include <common.h> - -#ifdef CONFIG_HARD_I2C -#include <i2c.h> -#include "i2c_export.h" -#include "i2c.h" - -#undef  I2CDBG0 -#undef  DEBUG - -/* Define a macro to use an optional application-layer print function, if - * one was passed to the I2C library during initialization.  If there was - * no function pointer passed, this protects against calling it.  Also define - * the global variable that holds the passed pointer. - */ -#define TIMEOUT (CFG_HZ/4) -#define PRINT if ( app_print ) app_print -static int (*app_print) (char *, ...); - -/******************* Internal to I2C Driver *****************/ -static unsigned int ByteToXmit = 0; -static unsigned int XmitByte = 0; -static unsigned char *XmitBuf = 0; -static unsigned int XmitBufEmptyStop = 0; -static unsigned int ByteToRcv = 0; -static unsigned int RcvByte = 0; -static unsigned char *RcvBuf = 0; -static unsigned int RcvBufFulStop = 0; -static unsigned int MasterRcvAddress = 0; - -/* Set by call to get_eumbbar during I2C_Initialize. - * This could be globally available to the I2C library, but there is - * an advantage to passing it as a parameter: it is already in a register - * and doesn't have to be loaded from memory.  Also, that is the way the - * I2C library was already implemented and I don't want to change it without - * a more detailed analysis. - * It is being set as a global variable in I2C_Initialize to hide it from - * the DINK application layer, because it is Kahlua-specific.  I think that - * get_eumbbar, load_runtime_reg, and store_runtime_reg should be defined in - * a Kahlua-specific library dealing with the embedded utilities memory block. - * Right now, get_eumbbar is defined in dink32/kahlua.s.  The other two are - * defined in dink32/drivers/i2c/i2c2.s. - */ -static unsigned int Global_eumbbar = 0; - -extern unsigned int load_runtime_reg (unsigned int eumbbar, -				      unsigned int reg); - -extern unsigned int store_runtime_reg (unsigned int eumbbar, -				       unsigned int reg, unsigned int val); - -/************************** API *****************/ - -/* Application Program Interface (API) are the calls provided by the I2C - * library to upper layer applications (i.e., DINK) to access the Kahlua - * I2C bus interface.  The functions and values that are part of this API - * are declared in i2c_export.h. - */ - -/*  Initialize I2C unit with the following: - *  driver's slave address - *  interrupt enabled - *  optional pointer to application layer print function - * - *  These parameters may be added: - *  desired clock rate - *  digital filter frequency sampling rate - * - *  This function must be called before I2C unit can be used. - */ -I2C_Status I2C_Initialize (unsigned char addr, -			   I2C_INTERRUPT_MODE en_int, -			   int (*p) (char *, ...)) -{ -	I2CStatus status; - -	/* establish the pointer, if there is one, to the application's "printf" */ -	app_print = p; - -	/* If this is the first call, get the embedded utilities memory block -	 * base address.  I'm not sure what to do about error handling here: -	 * if a non-zero value is returned, accept it. -	 */ -	if (Global_eumbbar == 0) -		Global_eumbbar = get_eumbbar (); -	if (Global_eumbbar == 0) { -		PRINT ("I2C_Initialize: can't find EUMBBAR\n"); -		return I2C_ERROR; -	} - -	/* validate the I2C address */ -	if (addr & 0x80) { -		PRINT ("I2C_Initialize, I2C address invalid:  %d 0x%x\n", -			   (unsigned int) addr, (unsigned int) addr); -		return I2C_ERROR; -	} - -	/* Call the internal I2C library function to perform work. -	 * Accept the default frequency sampling rate (no way to set it currently, -	 * via I2C_Init) and set the clock frequency to something reasonable. -	 */ -	status = I2C_Init (Global_eumbbar, (unsigned char) 0x31, addr, en_int); -	if (status != I2CSUCCESS) { -		PRINT ("I2C_Initialize: error in initiation\n"); -		return I2C_ERROR; -	} - -	/* all is well */ -	return I2C_SUCCESS; -} - - -/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV - * are implemented.  Both are only in polling mode. - * - * en_int controls interrupt/polling mode - * act is the type of transaction - * i2c_addr is the I2C address of the slave device - * data_addr is the address of the data on the slave device - * len is the length of data to send or receive - * buffer is the address of the data buffer - * stop = I2C_NO_STOP, don't signal STOP at end of transaction - *	  I2C_STOP, signal STOP at end of transaction - * retry is the timeout retry value, currently ignored - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction - *	  I2C_RESTART, this is a continuation of existing transaction - */ -I2C_Status I2C_do_transaction ( I2C_INTERRUPT_MODE en_int, -				I2C_TRANSACTION_MODE act, -				unsigned char i2c_addr, -				unsigned char data_addr, -				int len, -				char *buffer, -				I2C_STOP_MODE stop, -				int retry, I2C_RESTART_MODE rsta) -{ -	I2C_Status status; -	unsigned char data_addr_buffer[1]; - -#if 1 -/* This is a temporary work-around.  The I2C library breaks the protocol - * if it attempts to handle a data transmission in more than one - * transaction, so the data address and the actual data bytes are put - * into a single buffer before sending it to the library internal functions. - * The problem is related to being able to restart a transaction without - * sending the I2C device address or repeating the data address.  It may take - * a day or two to sort it all out, so I'll have to get back to it later. - * Look at I2C_Start to see about using some status flags (I'm not sure that - * "stop" and "rsta" are enough to reflect the states, maybe so; but the logic - * in the library is insufficient) to control correct handling of the protocol. - */ -	unsigned char dummy_buffer[257]; - -	if (act == I2C_MASTER_XMIT) { -		int i; - -		if (len > 256) -			return I2C_ERROR; -		for (i = 1; i <= len; i++) -			dummy_buffer[i] = buffer[i - 1]; -		dummy_buffer[0] = data_addr; -		status = I2C_do_buffer (en_int, act, i2c_addr, 1 + len, -					dummy_buffer, stop, retry, rsta); -		if (status != I2C_SUCCESS) { -			PRINT ("I2C_do_transaction: can't perform data transfer\n"); -			return I2C_ERROR; -		} -		return I2C_SUCCESS; -	} -#endif	/* end of temp work-around */ - -	/* validate requested transaction type */ -	if ((act != I2C_MASTER_XMIT) && (act != I2C_MASTER_RCV)) { -		PRINT ("I2C_do_transaction, invalid transaction request:  %d\n", -			act); -		return I2C_ERROR; -	} - -	/* range check the I2C address */ -	if (i2c_addr & 0x80) { -		PRINT ("I2C_do_transaction, I2C address out of range:  %d 0x%x\n", -			(unsigned int) i2c_addr, (unsigned int) i2c_addr); -		return I2C_ERROR; -	} else { -		data_addr_buffer[0] = data_addr; -	} - -	/* -	 * We first have to contact the slave device and transmit the -	 * data address. Be careful about the STOP and restart stuff. -	 * We don't want to signal STOP after sending the data -	 * address, but this could be a continuation if the -	 * application didn't release the bus after the previous -	 * transaction, by not sending a STOP after it. -	 */ -	status = I2C_do_buffer (en_int, I2C_MASTER_XMIT, i2c_addr, 1, -				data_addr_buffer, I2C_NO_STOP, retry, rsta); -	if (status != I2C_SUCCESS) { -		PRINT ("I2C_do_transaction: can't send data address for read\n"); -		return I2C_ERROR; -	} - -	/* The data transfer will be a continuation. */ -	rsta = I2C_RESTART; - -	/* now handle the user data */ -	status = I2C_do_buffer (en_int, act, i2c_addr, len, -				buffer, stop, retry, rsta); -	if (status != I2C_SUCCESS) { -		PRINT ("I2C_do_transaction: can't perform data transfer\n"); -		return I2C_ERROR; -	} - -	/* all is well */ -	return I2C_SUCCESS; -} - -/* This function performs the work for I2C_do_transaction.  The work is - * split into this function to enable I2C_do_transaction to first transmit - * the data address to the I2C slave device without putting the data address - * into the first byte of the buffer. - * - * en_int controls interrupt/polling mode - * act is the type of transaction - * i2c_addr is the I2C address of the slave device - * len is the length of data to send or receive - * buffer is the address of the data buffer - * stop = I2C_NO_STOP, don't signal STOP at end of transaction - *	  I2C_STOP, signal STOP at end of transaction - * retry is the timeout retry value, currently ignored - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction - *	  I2C_RESTART, this is a continuation of existing transaction - */ -static I2C_Status I2C_do_buffer (I2C_INTERRUPT_MODE en_int, -				 I2C_TRANSACTION_MODE act, -				 unsigned char i2c_addr, -				 int len, -				 unsigned char *buffer, -				 I2C_STOP_MODE stop, -				 int retry, I2C_RESTART_MODE rsta) -{ -	I2CStatus rval; -	unsigned int dev_stat; - -	if (act == I2C_MASTER_RCV) { -		/* set up for master-receive transaction */ -		rval = I2C_get (Global_eumbbar, i2c_addr, buffer, len, stop, rsta); -	} else { -		/* set up for master-transmit transaction */ -		rval = I2C_put (Global_eumbbar, i2c_addr, buffer, len, stop, rsta); -	} - -	/* validate the setup */ -	if (rval != I2CSUCCESS) { -		dev_stat = load_runtime_reg (Global_eumbbar, I2CSR); -		PRINT ("Error(I2C_do_buffer): control phase, code(0x%08x), status(0x%08x)\n", rval, dev_stat); -		I2C_Stop (Global_eumbbar); -		return I2C_ERROR; -	} - -	if (en_int == 1) { -		/* this should not happen, no interrupt handling yet */ -		return I2C_SUCCESS; -	} - -	/* this performs the polling action, when the transfer is completed, -	 * the status returned from I2C_Timer_Event will be I2CBUFFFULL or -	 * I2CBUFFEMPTY (rcv or xmit), I2CSUCCESS or I2CADDRESS indicates the -	 * transaction is not yet complete, anything else is an error. -	 */ -	while (rval == I2CSUCCESS || rval == I2CADDRESS) { -		int timeval = get_timer (0); - -		/* poll the device until something happens */ -		do { -			rval = I2C_Timer_Event (Global_eumbbar, 0); -		} -		while (rval == I2CNOEVENT && get_timer (timeval) < TIMEOUT); - -		/* check for error condition */ -		if (rval == I2CSUCCESS   || -		    rval == I2CBUFFFULL  || -		    rval == I2CBUFFEMPTY || -		    rval == I2CADDRESS) { -			;	/* do nothing */ -		} else { -			/* report the error condition */ -			dev_stat = load_runtime_reg (Global_eumbbar, I2CSR); -			PRINT ("Error(I2C_do_buffer):  code(0x%08x), status(0x%08x)\n", -				   rval, dev_stat); -			return I2C_ERROR; -		} -	} - -	/* all is well */ -	return I2C_SUCCESS; -} - -/** - * Note: - * - * In all following functions, - * the caller shall pass the configured embedded utility memory - * block base, EUMBBAR. - **/ - -/*********************************************************** - * function: I2C_put - * - * description: -   Send a buffer of data to the intended rcv_addr. - * If stop_flag is set, after the whole buffer - * is sent, generate a STOP signal provided that the - * receiver doesn't signal the STOP in the middle. - * I2C is the master performing transmitting. If - * no STOP signal is generated at the end of current - * transaction, the master can generate a START signal - * to another slave addr. - * - * note: this is master xmit API - *********************************************************/ -static I2CStatus I2C_put (unsigned int eumbbar, unsigned char rcv_addr,	/* receiver's address */ -	  unsigned char *buffer_ptr,	/* pointer of data to be sent */ -	  unsigned int length,	/* number of byte of in the buffer */ -	  unsigned int stop_flag,	/* 1 - signal STOP when buffer is empty -					 * 0 - no STOP signal when buffer is empty -					 */ -	  unsigned int is_cnt) -{					/* 1 - this is a restart, don't check MBB -					 * 0 - this is a new start, check MBB -					 */ -	if (buffer_ptr == 0 || length == 0) { -		return I2CERROR; -	} -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_put\n", __FILE__, __LINE__); -#endif - -	XmitByte = 0; -	ByteToXmit = length; -	XmitBuf = buffer_ptr; -	XmitBufEmptyStop = stop_flag; - -	RcvByte = 0; -	ByteToRcv = 0; -	RcvBuf = 0; - -	/* we are the master, start transaction */ -	return I2C_Start (eumbbar, rcv_addr, XMIT, is_cnt); -} - -/*********************************************************** - * function: I2C_get - * - * description: - * Receive a buffer of data from the desired sender_addr - * If stop_flag is set, when the buffer is full and the - * sender does not signal STOP, generate a STOP signal. - * I2C is the master performing receiving. If no STOP signal - * is generated, the master can generate a START signal - * to another slave addr. - * - * note: this is master receive API - **********************************************************/ -static I2CStatus I2C_get (unsigned int eumbbar, unsigned char rcv_from,	/* sender's address */ -		  unsigned char *buffer_ptr,	/* pointer of receiving buffer */ -		  unsigned int length,	/* length of the receiving buffer */ -		  unsigned int stop_flag,	/* 1 - signal STOP when buffer is full -						 * 0 - no STOP signal when buffer is full -						 */ -		  unsigned int is_cnt) -{						/* 1 - this is a restart, don't check MBB -						 * 0 - this is a new start, check MBB -						 */ -	if (buffer_ptr == 0 || length == 0) { -		return I2CERROR; -	} -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_get\n", __FILE__, __LINE__); -#endif - -	RcvByte = 0; -	ByteToRcv = length; -	RcvBuf = buffer_ptr; -	RcvBufFulStop = stop_flag; - -	XmitByte = 0; -	ByteToXmit = 0; -	XmitBuf = 0; - -	/* we are the master, start the transaction */ -	return I2C_Start (eumbbar, rcv_from, RCV, is_cnt); - -} - -#if 0	/* turn off dead code */ -/********************************************************* - * function: I2C_write - * - * description: - * Send a buffer of data to the requiring master. - * If stop_flag is set, after the whole buffer is sent, - * generate a STOP signal provided that the requiring - * receiver doesn't signal the STOP in the middle. - * I2C is the slave performing transmitting. - * - * Note: this is slave xmit API. - * - *       due to the current Kahlua design, slave transmitter - *       shall not signal STOP since there is no way - *       for master to detect it, causing I2C bus hung. - * - *       For the above reason, the stop_flag is always - *       set, i.e., 0. - * - *       programmer shall use the timer on Kahlua to - *       control the interval of data byte at the - *       master side. - *******************************************************/ -static I2CStatus I2C_write (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of data to be sent */ -		unsigned int length,	/* number of byte of in the buffer */ -		unsigned int stop_flag) -{					/* 1 - signal STOP when buffer is empty -					 * 0 - no STOP signal when buffer is empty -					 */ -	if (buffer_ptr == 0 || length == 0) { -		return I2CERROR; -	} - -	XmitByte = 0; -	ByteToXmit = length; -	XmitBuf = buffer_ptr; -	XmitBufEmptyStop = 0;	/* in order to avoid bus hung, ignored the user's stop_flag */ - -	RcvByte = 0; -	ByteToRcv = 0; -	RcvBuf = 0; - -	/* we are the slave, just wait for being called, or pull */ -	/* I2C_Timer_Event( eumbbar ); */ -} - -/****************************************************** - * function: I2C_read - * - * description: - * Receive a buffer of data from the sending master. - * If stop_flag is set, when the buffer is full and the - * sender does not signal STOP, generate a STOP signal. - * I2C is the slave performing receiving. - * - * note: this is slave receive API - ****************************************************/ -static I2CStatus I2C_read (unsigned int eumbbar, unsigned char *buffer_ptr,	/* pointer of receiving buffer */ -		   unsigned int length,	/* length of the receiving buffer */ -		   unsigned int stop_flag) -{					/* 1 - signal STOP when buffer is full -					 * 0 - no STOP signal when buffer is full -					 */ -	if (buffer_ptr == 0 || length == 0) { -		return I2CERROR; -	} - -	RcvByte = 0; -	ByteToRcv = length; -	RcvBuf = buffer_ptr; -	RcvBufFulStop = stop_flag; - -	XmitByte = 0; -	ByteToXmit = 0; -	XmitBuf = 0; - -	/* wait for master to call us, or poll */ -	/* I2C_Timer_Event( eumbbar ); */ -} -#endif	/* turn off dead code */ - -/********************************************************* - * function: I2c_Timer_Event - * - * description: - * if interrupt is not used, this is the timer event handler. - * After each fixed time interval, this function can be called - * to check the I2C status and call appropriate function to - * handle the status event. - ********************************************************/ -static I2CStatus I2C_Timer_Event (unsigned int eumbbar, -				  I2CStatus (*handler) (unsigned int)) -{ -	I2C_STAT stat; - -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_Timer_Event\n", __FILE__, __LINE__); -#endif - -	stat = I2C_Get_Stat (eumbbar); - -	if (stat.mif == 1) { -		if (handler == 0) { -			return I2C_ISR (eumbbar); -		} else { -			return (*handler) (eumbbar); -		} -	} - -	return I2CNOEVENT; -} - - -/****************** Device I/O function *****************/ - -/****************************************************** - * function: I2C_Start - * - * description: Generate a START signal in the desired mode. - *		I2C is the master. - * - *		Return I2CSUCCESS if no error. - * - * note: - ****************************************************/ -static I2CStatus I2C_Start (unsigned int eumbbar, unsigned char slave_addr,	/* address of the receiver */ -			I2C_MODE mode,	/* XMIT(1) - put (write) -					 * RCV(0)  - get (read) -					 */ -			unsigned int is_cnt) -{					/* 1 - this is a restart, don't check MBB -					 * 0 - this is a new start -					 */ -	unsigned int tmp = 0; -	I2C_STAT stat; -	I2C_CTRL ctrl; - -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_Start addr 0x%x mode %d cnt %d\n", __FILE__, -		   __LINE__, slave_addr, mode, is_cnt); -#endif - -	ctrl = I2C_Get_Ctrl (eumbbar); - -	/* first make sure I2C has been initialized */ -	if (ctrl.men == 0) { -		return I2CERROR; -	} - -	/* next make sure bus is idle */ -	stat = I2C_Get_Stat (eumbbar); - -	if (is_cnt == 0 && stat.mbb == 1) { -		/* sorry, we lost */ -		return I2CBUSBUSY; -	} else if (is_cnt == 1 && stat.mif == 1 && stat.mal == 0) { -		/* sorry, we lost the bus */ -		return I2CALOSS; -	} - - -	/* OK, I2C is enabled and we have the bus */ - -	/* prepare to write the slave address */ -	ctrl.msta = 1; -	ctrl.mtx = 1; -	ctrl.txak = 0; -	ctrl.rsta = is_cnt;		/* set the repeat start bit */ -	I2C_Set_Ctrl (eumbbar, ctrl); - -	/* write the slave address and xmit/rcv mode bit */ -	tmp = load_runtime_reg (eumbbar, I2CDR); -	tmp = (tmp & 0xffffff00) | -	      ((slave_addr & 0x007f) << 1) | -	      (mode == XMIT ? 0x0 : 0x1); -	store_runtime_reg (eumbbar, I2CDR, tmp); - -	if (mode == RCV) { -		MasterRcvAddress = 1; -	} else { -		MasterRcvAddress = 0; -	} - -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_Start exit\n", __FILE__, __LINE__); -#endif - -	/* wait for the interrupt or poll  */ -	return I2CSUCCESS; -} - -/*********************************************************** - * function: I2c_Stop - * - * description: Generate a STOP signal to terminate the master - *		transaction. - *		return I2CSUCCESS - * - **********************************************************/ -static I2CStatus I2C_Stop (unsigned int eumbbar) -{ -	I2C_CTRL ctrl; - -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_Stop enter\n", __FILE__, __LINE__); -#endif - -	ctrl = I2C_Get_Ctrl (eumbbar); -	ctrl.msta = 0; -	I2C_Set_Ctrl (eumbbar, ctrl); - -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_Stop exit\n", __FILE__, __LINE__); -#endif - -	return I2CSUCCESS; -} - -/**************************************************** - * function: I2C_Master_Xmit - * - * description: Master sends one byte of data to - *		slave target - * - *		return I2CSUCCESS if the byte transmitted. - *		Otherwise no-zero - * - * Note: condition must meet when this function is called: - *       I2CSR(MIF) == 1 && I2CSR(MCF)  == 1  && I2CSR(RXAK) == 0 - *       I2CCR(MSTA) == 1  && I2CCR(MTX) == 1 - * - ***************************************************/ -static I2CStatus I2C_Master_Xmit (unsigned int eumbbar) -{ -	unsigned int val; - -	if (ByteToXmit > 0) { - -		if (ByteToXmit == XmitByte) { -			/* all xmitted */ -			ByteToXmit = 0; - -			if (XmitBufEmptyStop == 1) { -				I2C_Stop (eumbbar); -			} - -			return I2CBUFFEMPTY; - -		} -#ifdef I2CDBG0 -		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, -			   *(XmitBuf + XmitByte)); -#endif - -		val = *(XmitBuf + XmitByte); -		val &= 0x000000ff; -		store_runtime_reg (eumbbar, I2CDR, val); -		XmitByte++; - -		return I2CSUCCESS; - -	} - -	return I2CBUFFEMPTY; -} - -/*********************************************** - * function: I2C_Master_Rcv - * - * description: master reads one byte data - *		from slave source - * - *		return I2CSUCCESS if no error - * - * Note: condition must meet when this function is called: - *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && - *       I2CCR(MSTA) == 1 && I2CCR(MTX) == 0 - * - ***********************************************/ -static I2CStatus I2C_Master_Rcv (unsigned int eumbbar) -{ -	I2C_CTRL ctrl; -	unsigned int val; - -	if (ByteToRcv > 0) { - -		if (ByteToRcv - RcvByte == 2 && RcvBufFulStop == 1) { -			/* master requests more than or equal to 2 bytes -			 * we are reading 2nd to last byte -			 */ - -			/* we need to set I2CCR(TXAK) to generate a STOP */ -			ctrl = I2C_Get_Ctrl (eumbbar); -			ctrl.txak = 1; -			I2C_Set_Ctrl (eumbbar, ctrl); - -			/* Kahlua will automatically generate a STOP -			 * next time a transaction happens -			 */ - -			/* note: the case of master requesting one byte is -			 *       handled in I2C_ISR -			 */ -		} - -		/* generat a STOP before reading the last byte */ -		if (RcvByte + 1 == ByteToRcv && RcvBufFulStop == 1) { -			I2C_Stop (eumbbar); -		} - -		val = load_runtime_reg (eumbbar, I2CDR); -		*(RcvBuf + RcvByte) = val & 0xFF; - -#ifdef I2CDBG0 -		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, -			   *(RcvBuf + RcvByte)); -#endif - -		RcvByte++; - -		if (ByteToRcv == RcvByte) { -			ByteToRcv = 0; - -			return I2CBUFFFULL; -		} - -		return I2CSUCCESS; -	} - -	return I2CBUFFFULL; - -} - -/**************************************************** - * function: I2C_Slave_Xmit - * - * description: Slave sends one byte of data to - *		requesting destination - * - *	  return SUCCESS if the byte transmitted. Otherwise - *	  No-zero - * - * Note: condition must meet when this function is called: - *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 &&  I2CSR(RXAK) = 0 - *       I2CCR(MSTA) == 0  && I2CCR(MTX) == 1 - * - ***************************************************/ -static I2CStatus I2C_Slave_Xmit (unsigned int eumbbar) -{ -	unsigned int val; - -	if (ByteToXmit > 0) { - -		if (ByteToXmit == XmitByte) { -			/* no more data to send */ -			ByteToXmit = 0; - -			/* -			 * do not toggle I2CCR(MTX). Doing so will -			 * cause bus-hung since current Kahlua design -			 * does not give master a way to detect slave -			 * stop. It is always a good idea for master -			 * to use timer to prevent the long long -			 * delays -			 */ - -			return I2CBUFFEMPTY; -		} -#ifdef I2CDBG -		PRINT ("%s(%d): xmit 0x%02x\n", __FILE__, __LINE__, -			   *(XmitBuf + XmitByte)); -#endif - -		val = *(XmitBuf + XmitByte); -		val &= 0x000000ff; -		store_runtime_reg (eumbbar, I2CDR, val); -		XmitByte++; - -		return I2CSUCCESS; -	} - -	return I2CBUFFEMPTY; -} - -/*********************************************** - * function: I2C_Slave_Rcv - * - * description: slave reads one byte data - *		from master source - * - *		return I2CSUCCESS if no error otherwise non-zero - * - * Note: condition must meet when this function is called: - *       I2CSR(MIF) == 1 && I2CSR(MCF) == 1 && - *       I2CCR(MSTA) == 0 && I2CCR(MTX)  = 0 - * - ***********************************************/ -static I2CStatus I2C_Slave_Rcv (unsigned int eumbbar) -{ -	unsigned int val; -	I2C_CTRL ctrl; - -	if (ByteToRcv > 0) { -		val = load_runtime_reg (eumbbar, I2CDR); -		*(RcvBuf + RcvByte) = val & 0xff; -#ifdef I2CDBG -		PRINT ("%s(%d): rcv 0x%02x\n", __FILE__, __LINE__, -			   *(RcvBuf + RcvByte)); -#endif -		RcvByte++; - -		if (ByteToRcv == RcvByte) { -			if (RcvBufFulStop == 1) { -				/* all done */ -				ctrl = I2C_Get_Ctrl (eumbbar); -				ctrl.txak = 1; -				I2C_Set_Ctrl (eumbbar, ctrl); -			} - -			ByteToRcv = 0; -			return I2CBUFFFULL; -		} - -		return I2CSUCCESS; -	} - -	return I2CBUFFFULL; -} - -/****************** Device Control Function *************/ - -/********************************************************* - * function: I2C_Init - * - * description: Initialize I2C unit with desired frequency divider, - *		master's listening address, with interrupt enabled - *		or disabled. - * - * note: - ********************************************************/ -static I2CStatus I2C_Init (unsigned int eumbbar, unsigned char fdr,	/* frequency divider */ -		   unsigned char slave_addr,	/* driver's address used for receiving */ -		   unsigned int en_int) -{						/* 1 - enable I2C interrupt -						 * 0 - disable I2C interrup -						 */ -	I2C_CTRL ctrl; -	unsigned int tmp; - -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_Init enter\n", __FILE__, __LINE__); -#endif - -	ctrl = I2C_Get_Ctrl (eumbbar); -	/* disable the I2C module before we change everything */ -	ctrl.men = 0; -	I2C_Set_Ctrl (eumbbar, ctrl); - -	/* set the frequency diver */ -	tmp = load_runtime_reg (eumbbar, I2CFDR); -	tmp = (tmp & 0xffffffc0) | (fdr & 0x3f); -	store_runtime_reg (eumbbar, I2CFDR, tmp); - -	/* Set our listening (slave) address */ -	tmp = load_runtime_reg (eumbbar, I2CADR); -	tmp = (tmp & 0xffffff01) | ((slave_addr & 0x7f) << 1); -	store_runtime_reg (eumbbar, I2CADR, tmp); - -	/* enable I2C with desired interrupt setting */ -	ctrl.men = 1; -	ctrl.mien = en_int & 0x1; -	I2C_Set_Ctrl (eumbbar, ctrl); -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_Init exit\n", __FILE__, __LINE__); -#endif - -	return I2CSUCCESS; - -} - -/***************************************** - * function I2c_Get_Stat - * - * description: Query I2C Status, i.e., read I2CSR - * - ****************************************/ -static I2C_STAT I2C_Get_Stat (unsigned int eumbbar) -{ -	unsigned int temp; -	I2C_STAT stat; - -	temp = load_runtime_reg (eumbbar, I2CSR); - -#ifdef I2CDBG0 -	PRINT ("%s(%d): get stat = 0x%08x\n", __FILE__, __LINE__, temp); -#endif - -	stat.rsrv0 = (temp & 0xffffff00) >> 8; -	stat.mcf   = (temp & 0x00000080) >> 7; -	stat.maas  = (temp & 0x00000040) >> 6; -	stat.mbb   = (temp & 0x00000020) >> 5; -	stat.mal   = (temp & 0x00000010) >> 4; -	stat.rsrv1 = (temp & 0x00000008) >> 3; -	stat.srw   = (temp & 0x00000004) >> 2; -	stat.mif   = (temp & 0x00000002) >> 1; -	stat.rxak  = (temp & 0x00000001); -	return stat; -} - -/********************************************* - * function: I2c_Set_Ctrl - * - * description: Change I2C Control bits, - *		i.e., write to I2CCR - * - ********************************************/ -static void I2C_Set_Ctrl (unsigned int eumbbar, I2C_CTRL ctrl) -{						/* new control value */ -	unsigned int temp = load_runtime_reg (eumbbar, I2CCR); - -	temp &= 0xffffff03; -	temp |= ((ctrl.men  & 0x1) << 7); -	temp |= ((ctrl.mien & 0x1) << 6); -	temp |= ((ctrl.msta & 0x1) << 5); -	temp |= ((ctrl.mtx  & 0x1) << 4); -	temp |= ((ctrl.txak & 0x1) << 3); -	temp |= ((ctrl.rsta & 0x1) << 2); -#ifdef I2CDBG0 -	PRINT ("%s(%d): set ctrl = 0x%08x\n", __FILE__, __LINE__, temp); -#endif -	store_runtime_reg (eumbbar, I2CCR, temp); - -} - -/***************************************** - * function: I2C_Get_Ctrl - * - * description: Query I2C Control bits, - *		i.e., read I2CCR - *****************************************/ -static I2C_CTRL I2C_Get_Ctrl (unsigned int eumbbar) -{ -	union { -		I2C_CTRL ctrl; -		unsigned int temp; -	} s; - -	s.temp = load_runtime_reg (eumbbar, I2CCR); -#ifdef I2CDBG0 -	PRINT ("%s(%d): get ctrl = 0x%08x\n", __FILE__, __LINE__, s.temp); -#endif - -	return s.ctrl; -} - - -/**************************************** - * function: I2C_Slave_Addr - * - * description: Process slave address phase. - *		return I2CSUCCESS if no error - * - * note: Precondition for calling this function: - *       I2CSR(MIF) == 1 && - *       I2CSR(MAAS) == 1 - ****************************************/ -static I2CStatus I2C_Slave_Addr (unsigned int eumbbar) -{ -	I2C_STAT stat = I2C_Get_Stat (eumbbar); -	I2C_CTRL ctrl = I2C_Get_Ctrl (eumbbar); - -	if (stat.srw == 1) { -		/* we are asked to xmit */ -		ctrl.mtx = 1; -		I2C_Set_Ctrl (eumbbar, ctrl);	/* set MTX */ -		return I2C_Slave_Xmit (eumbbar); -	} - -	/* we are asked to receive data */ -	ctrl.mtx = 0; -	I2C_Set_Ctrl (eumbbar, ctrl); -	(void) load_runtime_reg (eumbbar, I2CDR);	/* do a fake read to start */ - -	return I2CADDRESS; -} - -/*********************************************** - * function: I2C_ISR - * - * description: I2C Interrupt service routine - * - * note: Precondition: - *      I2CSR(MIF) == 1 - **********************************************/ -static I2CStatus I2C_ISR (unsigned int eumbbar) -{ -	I2C_STAT stat; -	I2C_CTRL ctrl; - -#ifdef I2CDBG0 -	PRINT ("%s(%d): I2C_ISR\n", __FILE__, __LINE__); -#endif - -	stat = I2C_Get_Stat (eumbbar); -	ctrl = I2C_Get_Ctrl (eumbbar); - -	/* clear MIF */ -	stat.mif = 0; - -	/* Now let see what kind of event this is */ -	if (stat.mcf == 1) { -		/* transfer compete */ - -		/* clear the MIF bit */ -		I2C_Set_Stat (eumbbar, stat); - -		if (ctrl.msta == 1) { -			/* master */ -			if (ctrl.mtx == 1) { -				/* check if this is the address phase for master receive */ -				if (MasterRcvAddress == 1) { -					/* Yes, it is the address phase of master receive */ -					ctrl.mtx = 0; -					/* now check how much we want to receive */ -					if (ByteToRcv == 1 && RcvBufFulStop == 1) { -						ctrl.txak = 1; -					} - -					I2C_Set_Ctrl (eumbbar, ctrl); -					(void) load_runtime_reg (eumbbar, I2CDR);	/* fake read first */ - -					MasterRcvAddress = 0; -					return I2CADDRESS; - -				} - -				/* master xmit */ -				if (stat.rxak == 0) { -					/* slave has acknowledged */ -					return I2C_Master_Xmit (eumbbar); -				} - -				/* slave has not acknowledged yet, generate a STOP */ -				if (XmitBufEmptyStop == 1) { -					ctrl.msta = 0; -					I2C_Set_Ctrl (eumbbar, ctrl); -				} - -				return I2CSUCCESS; -			} - -			/* master receive */ -			return I2C_Master_Rcv (eumbbar); -		} - -		/* slave */ -		if (ctrl.mtx == 1) { -			/* slave xmit */ -			if (stat.rxak == 0) { -				/* master has acknowledged */ -				return I2C_Slave_Xmit (eumbbar); -			} - -			/* master has not acknowledged, wait for STOP */ -			/* do nothing for preventing bus from hung */ -			return I2CSUCCESS; -		} - -		/* slave rcv */ -		return I2C_Slave_Rcv (eumbbar); - -	} else if (stat.maas == 1) { -		/* received a call from master */ - -		/* clear the MIF bit */ -		I2C_Set_Stat (eumbbar, stat); - -		/* master is calling us, process the address phase */ -		return I2C_Slave_Addr (eumbbar); -	} else { -		/* has to be arbitration lost */ -		stat.mal = 0; -		I2C_Set_Stat (eumbbar, stat); - -		ctrl.msta = 0;			/* return to receive mode */ -		I2C_Set_Ctrl (eumbbar, ctrl); -	} - -	return I2CSUCCESS; - -} - -/****************************************************** - * function: I2C_Set_Stat - * - * description: modify the I2CSR - * - *****************************************************/ -static void I2C_Set_Stat (unsigned int eumbbar, I2C_STAT stat) -{ -	union { -		unsigned int val; -		I2C_STAT stat; -	} s_tmp; -	union { -		unsigned int val; -		I2C_STAT stat; -	} s; - -	s.val = load_runtime_reg (eumbbar, I2CSR); -	s.val &= 0xffffff08; -	s_tmp.stat = stat; -	s.val |= (s_tmp.val & 0xf7); - -#ifdef I2CDBG0 -	PRINT ("%s(%d): set stat = 0x%08x\n", __FILE__, __LINE__, s.val); -#endif - -	store_runtime_reg (eumbbar, I2CSR, s.val); - -} - -/****************************************************** - * The following are routines to glue the rest of - * U-Boot to the Sandpoint I2C driver. - *****************************************************/ - -void i2c_init (int speed, int slaveadd) -{ -#ifdef CFG_I2C_INIT_BOARD -	/* -	 * call board specific i2c bus reset routine before accessing the -	 * environment, which might be in a chip on that bus. For details -	 * about this problem see doc/I2C_Edge_Conditions. -	 */ -	i2c_init_board(); -#endif - -#ifdef DEBUG -	I2C_Initialize (0x7f, 0, (void *) printf); -#else -	I2C_Initialize (0x7f, 0, 0); -#endif -} - -int i2c_probe (uchar chip) -{ -	int tmp; - -	/* -	 * Try to read the first location of the chip.  The underlying -	 * driver doesn't appear to support sending just the chip address -	 * and looking for an <ACK> back. -	 */ -	udelay(10000); -	return i2c_read (chip, 0, 1, (char *)&tmp, 1); -} - -int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) -{ -	I2CStatus status; -	uchar xaddr[4]; - -	if (alen > 0) { -		xaddr[0] = (addr >> 24) & 0xFF; -		xaddr[1] = (addr >> 16) & 0xFF; -		xaddr[2] = (addr >> 8) & 0xFF; -		xaddr[3] = addr & 0xFF; - -		status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen, -					&xaddr[4 - alen], I2C_NO_STOP, 1, -					I2C_NO_RESTART); -		if (status != I2C_SUCCESS) { -			PRINT ("i2c_read: can't send data address for read\n"); -			return 1; -		} -	} - -	/* The data transfer will be a continuation. */ -	status = I2C_do_buffer (0, I2C_MASTER_RCV, chip, len, -				buffer, I2C_STOP, 1, (alen > 0 ? I2C_RESTART : -				I2C_NO_RESTART)); - -	if (status != I2C_SUCCESS) { -		PRINT ("i2c_read: can't perform data transfer\n"); -		return 1; -	} - -	return 0; -} - -int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) -{ -	I2CStatus status; -	uchar dummy_buffer[I2C_RXTX_LEN + 2]; -	uchar *p; -	int i; - -	/* fill in address in big endian order */ -	for (i=alen-1; i>=0; --i) { -		buffer[i] = addr & 0xFF; -		addr >>= 8; -	} -	/* fill in data */ -	p = dummy_buffer + alen; - -	for (i=0; i<len; ++i) -		*p++ = *buffer++; - -	status = I2C_do_buffer (0, I2C_MASTER_XMIT, chip, alen + len, -				dummy_buffer, I2C_STOP, 1, I2C_NO_RESTART); - -#ifdef CFG_EEPROM_PAGE_WRITE_DELAY_MS -	udelay(CFG_EEPROM_PAGE_WRITE_DELAY_MS * 1000); -#endif -	if (status != I2C_SUCCESS) { -		PRINT ("i2c_write: can't perform data transfer\n"); -		return 1; -	} - -	return 0; -} - -uchar i2c_reg_read (uchar i2c_addr, uchar reg) -{ -	char buf[1]; - -	i2c_init (0, 0); - -	i2c_read (i2c_addr, reg, 1, buf, 1); - -	return (buf[0]); -} - -void i2c_reg_write (uchar i2c_addr, uchar reg, uchar val) -{ -	i2c_init (0, 0); - -	i2c_write (i2c_addr, reg, 1, &val, 1); -} - -#endif	/* CONFIG_HARD_I2C */ diff --git a/cpu/mpc824x/drivers/i2c/i2c2.S b/cpu/mpc824x/drivers/i2c/i2c2.S deleted file mode 100644 index 3fd7e03fe..000000000 --- a/cpu/mpc824x/drivers/i2c/i2c2.S +++ /dev/null @@ -1,52 +0,0 @@ -/************************************** - * - * copyright @ Motorola, 1999 - * - **************************************/ - -#include <config.h> -#ifdef CONFIG_HARD_I2C -#include <ppc_asm.tmpl> -#include <asm/mmu.h> -/********************************************************** - * function: load_runtime_reg - * - * input:  r3 - value of eumbbar - *         r4 - register offset in embedded utility space - * - * output: r3 - register content - **********************************************************/ -	.text -	.align 2 -	.global load_runtime_reg -load_runtime_reg: - -/*	xor r5,r5,r5 - *	or  r5,r5,r3 - * - *	lwbrx	r3,r4,r5 - */ -	lwbrx r3,r4,r3 -	sync - -	bclr 20, 0 - -/**************************************************************** - * function: store_runtime_reg - * - * input: r3 - value of eumbbar - *        r4 - register offset in embedded utility space - *        r5 - new value to be stored - * - ****************************************************************/ -	.text -	.align 2 -	.global store_runtime_reg -store_runtime_reg: - -	stwbrx r5,  r4, r3 -	sync - -	bclr   20,0 - -#endif /* CONFIG_HARD_I2C */ diff --git a/cpu/mpc824x/drivers/i2c/i2c_export.h b/cpu/mpc824x/drivers/i2c/i2c_export.h deleted file mode 100644 index 6264d189b..000000000 --- a/cpu/mpc824x/drivers/i2c/i2c_export.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef I2C_EXPORT_H -#define I2C_EXPORT_H - -/**************************************************** - * - * Copyright Motrola 1999 - * - ****************************************************/ - -/* These are the defined return values for the I2C_do_transaction function. - * Any non-zero value indicates failure.  Failure modes can be added for - * more detailed error reporting. - */ -typedef enum _i2c_status -{ - I2C_SUCCESS     = 0, - I2C_ERROR, -} I2C_Status; - -/* These are the defined tasks for I2C_do_transaction. - * Modes for SLAVE_RCV and SLAVE_XMIT will be added. - */ -typedef enum _i2c_transaction_mode -{ -	I2C_MASTER_RCV =  0, -	I2C_MASTER_XMIT = 1, -} I2C_TRANSACTION_MODE; - -typedef enum _i2c_interrupt_mode -{ -	I2C_INT_DISABLE =  0, -	I2C_INT_ENABLE = 1, -} I2C_INTERRUPT_MODE; - -typedef enum _i2c_stop -{ -	I2C_NO_STOP =  0, -	I2C_STOP = 1, -} I2C_STOP_MODE; - -typedef enum _i2c_restart -{ -	I2C_NO_RESTART =  0, -	I2C_RESTART = 1, -} I2C_RESTART_MODE; - -/******************** App. API ******************** - * The application API is for user level application - * to use the functionality provided by I2C driver. - * This is a "generic" I2C interface, it should contain - * nothing specific to the Kahlua implementation. - * Only the generic functions are exported by the library. - * - * Note: Its App.s responsibility to swap the data - *       byte. In our API, we just transfer whatever - *       we are given - **************************************************/ - - -/*  Initialize I2C unit with the following: - *  driver's slave address - *  interrupt enabled - *  optional pointer to application layer print function - * - *  These parameters may be added: - *  desired clock rate - *  digital filter frequency sampling rate - * - *  This function must be called before I2C unit can be used. - */ -extern I2C_Status I2C_Initialize( -	unsigned char addr,            /* driver's I2C slave address */ -	I2C_INTERRUPT_MODE en_int,     /* 1 - enable I2C interrupt -					* 0 - disable I2C interrupt -					*/ -	int (*app_print_function)(char *,...)); /* pointer to optional "printf" -						 * provided by application -						 */ - -/* Perform the given I2C transaction, only MASTER_XMIT and MASTER_RCV - * are implemented.  Both are only in polling mode. - * - * en_int controls interrupt/polling mode - * act is the type of transaction - * addr is the I2C address of the slave device - * len is the length of data to send or receive - * buffer is the address of the data buffer - * stop = I2C_NO_STOP, don't signal STOP at end of transaction - *        I2C_STOP, signal STOP at end of transaction - * retry is the timeout retry value, currently ignored - * rsta = I2C_NO_RESTART, this is not continuation of existing transaction - *        I2C_RESTART, this is a continuation of existing transaction - */ -extern I2C_Status I2C_do_transaction( I2C_INTERRUPT_MODE en_int, -				      I2C_TRANSACTION_MODE act, -				      unsigned char i2c_addr, -				      unsigned char data_addr, -				      int len, -				      char *buffer, -				      I2C_STOP_MODE stop, -				      int retry, -				      I2C_RESTART_MODE rsta); -#endif diff --git a/cpu/mpc824x/start.S b/cpu/mpc824x/start.S index a22137ceb..9ff052c3b 100644 --- a/cpu/mpc824x/start.S +++ b/cpu/mpc824x/start.S @@ -526,11 +526,26 @@ relocate_code:  	stwu	r0,-4(r7)  	bdnz	3b +4: +#if !defined(CONFIG_BMW) +/* Unlock the data cache and invalidate locked area */ +	xor	r0, r0, r0 +	mtspr	1011, r0 +	lis	r4, CFG_INIT_RAM_ADDR@h +	ori	r4, r4, CFG_INIT_RAM_ADDR@l +	li	r0, 128 +	mtctr	r0 +41: +	dcbi	r0, r4 +	addi	r4, r4, 32 +	bdnz	41b +#endif +  /*   * Now flush the cache: note that we must start from a cache aligned   * address. Otherwise we might miss one cache line.   */ -4:	cmpwi	r6,0 +	cmpwi	r6,0  	add	r5,r3,r5  	beq	7f		/* Always flush prefetch queue in any case */  	subi	r0,r6,1 diff --git a/cpu/pxa/mmc.c b/cpu/pxa/mmc.c index 9e6e1e3d3..4363a5fde 100644 --- a/cpu/pxa/mmc.c +++ b/cpu/pxa/mmc.c @@ -26,11 +26,19 @@  #include <mmc.h>  #include <asm/errno.h>  #include <asm/arch/hardware.h> +#include <part.h>  #ifdef CONFIG_MMC  extern int -fat_register_read(int(*block_read)(int device, ulong blknr, ulong blkcnt, uchar *buffer)); +fat_register_device(block_dev_desc_t *dev_desc, int part_no); + +static block_dev_desc_t mmc_dev; + +block_dev_desc_t * mmc_get_dev(int dev) +{ +	return ((block_dev_desc_t *)&mmc_dev); +}  /*   * FIXME needs to read cid and csd info to determine block size @@ -379,9 +387,9 @@ mmc_write(uchar *src, ulong dst, int size)  	return 0;  } -int +ulong  /****************************************************/ -mmc_bread(int dev_num, ulong blknr, ulong blkcnt, uchar *dst) +mmc_bread(int dev_num, ulong blknr, ulong blkcnt, ulong *dst)  /****************************************************/  {  	int mmc_block_size = MMC_BLOCK_SIZE; @@ -441,6 +449,21 @@ mmc_init(int verbose)  			printf("Month = %d\n",cid->month);  			printf("Year = %d\n",1997 + cid->year);  		} +		/* fill in device description */ +		mmc_dev.if_type = IF_TYPE_MMC; +		mmc_dev.dev = 0; +		mmc_dev.lun = 0; +		mmc_dev.type = 0; +		/* FIXME fill in the correct size (is set to 32MByte) */ +		mmc_dev.blksz = 512; +		mmc_dev.lba = 0x10000; +		sprintf(mmc_dev.vendor,"Man %02x%02x%02x Snr %02x%02x%02x", +				cid->id[0], cid->id[1], cid->id[2], +				cid->sn[0], cid->sn[1], cid->sn[2]); +		sprintf(mmc_dev.product,"%s",cid->name); +		sprintf(mmc_dev.revision,"%x %x",cid->hwrev, cid->fwrev); +		mmc_dev.removable = 0; +		mmc_dev.block_read = mmc_bread;  		/* MMC exists, get CSD too */  		resp = mmc_cmd(MMC_CMD_SET_RCA, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1); @@ -458,7 +481,7 @@ mmc_init(int verbose)  	MMC_CLKRT = 0;	/* 20 MHz */  	resp = mmc_cmd(7, MMC_DEFAULT_RCA, 0, MMC_CMDAT_R1); -	fat_register_read(mmc_bread); +	fat_register_device(&mmc_dev,1); /* partitions start counting with 1 */   	return rc;  } diff --git a/disk/part_dos.c b/disk/part_dos.c index 32333c797..d05f6509f 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -67,6 +67,17 @@ static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_nu  		(is_extended (p->sys_ind) ? " Extd" : ""));  } +static int test_block_type(unsigned char *buffer) +{ +	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || +	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { +		return (-1); +	} /* no DOS Signature at all */ +	if(strncmp(&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0) +		return DOS_PBR; /* is PBR */ +	return DOS_MBR;	    /* Is MBR */ +} +  int test_part_dos (block_dev_desc_t *dev_desc)  { @@ -94,14 +105,18 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s  			dev_desc->dev, ext_part_sector);  		return;  	} -	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || -		buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { +	i=test_block_type(buffer); +	if(i==-1) {  		printf ("bad MBR sector signature 0x%02x%02x\n",  			buffer[DOS_PART_MAGIC_OFFSET],  			buffer[DOS_PART_MAGIC_OFFSET + 1]);  		return;  	} - +	if(i==DOS_PBR) { +		printf ("    1\t\t         0\t%10ld\t%2x\n", +			dev_desc->lba, buffer[DOS_PBR_MEDIA_TYPE_OFFSET]); +		return; +	}  	/* Print all primary/logical partitions */  	pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);  	for (i = 0; i < 4; i++, pt++) { diff --git a/disk/part_dos.h b/disk/part_dos.h index cc3fa81d7..ac93f20b3 100644 --- a/disk/part_dos.h +++ b/disk/part_dos.h @@ -34,6 +34,10 @@  #endif  #define DOS_PART_TBL_OFFSET	0x1be  #define DOS_PART_MAGIC_OFFSET	0x1fe +#define DOS_PBR_FSTYPE_OFFSET	0x36 +#define DOS_PBR_MEDIA_TYPE_OFFSET	0x15 +#define DOS_MBR	0 +#define DOS_PBR	1  typedef struct dos_partition {  	unsigned char boot_ind;		/* 0x80 - active			*/ diff --git a/fs/fat/fat.c b/fs/fat/fat.c index 9f0156719..6a6c5be01 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -29,6 +29,7 @@  #include <config.h>  #include <fat.h>  #include <asm/byteorder.h> +#include <part.h>  #if (CONFIG_COMMANDS & CFG_CMD_FAT) @@ -44,26 +45,70 @@ downcase(char *str)  	}  } -int (*dev_block_read)(int device, __u32 blknr, __u32 blkcnt, __u8 *buffer) = 0; +static  block_dev_desc_t *cur_dev = NULL; +static unsigned long part_offset = 0; +static int cur_part = 1; + +#define DOS_PART_TBL_OFFSET	0x1be +#define DOS_PART_MAGIC_OFFSET	0x1fe +#define DOS_FS_TYPE_OFFSET	0x36  int disk_read (__u32 startblock, __u32 getsize, __u8 * bufptr)  { -	/* FIXME we need to determine the start block of the -	 * partition where the DOS FS resides -	 */ -	startblock += 32; - -	if (dev_block_read) { -		return dev_block_read (0, startblock, getsize, bufptr); +	startblock += part_offset; +	if (cur_dev == NULL) +		return -1; +	if (cur_dev->block_read) { +		return cur_dev->block_read (cur_dev->dev, startblock, getsize, (unsigned long *)bufptr);  	}  	return -1;  }  int -fat_register_read (int (*block_read)(int, __u32, __u32, __u8 *)) +fat_register_device(block_dev_desc_t *dev_desc, int part_no)  { -	dev_block_read = block_read; +	unsigned char buffer[SECTOR_SIZE]; + +	if (!dev_desc->block_read) +		return -1; +	cur_dev=dev_desc; +	/* check if we have a MBR (on floppies we have only a PBR) */ +	if (dev_desc->block_read (dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { +		printf ("** Can't read from device %d **\n", dev_desc->dev); +		return -1; +	} +	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || +		buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { +		/* no signature found */ +		return -1; +	} +	if(!strncmp(&buffer[DOS_FS_TYPE_OFFSET],"FAT",3)) { +		/* ok, we assume we are on a PBR only */ +		cur_part = 1; +		part_offset=0; +	} +	else { +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) +		disk_partition_t info; +		if(!get_partition_info(dev_desc, part_no, &info)) { +			part_offset = info.start; +			cur_part = part_no; +		} +		else { +			printf ("** Partition %d not valid on device %d **\n",part_no,dev_desc->dev); +			return -1; +		} +#else +		/* FIXME we need to determine the start block of the +		 * partition where the DOS FS resides. This can be done +		 * by using the get_partition_info routine. For this +		 * purpose the libpart must be included. +		 */ +		part_offset=32; +		cur_part = 1; +#endif +	}  	return 0;  } @@ -246,25 +291,21 @@ get_cluster(fsdata *mydata, __u32 clustnum, __u8 *buffer, unsigned long size)  	}  	FAT_DPRINT("gc - clustnum: %d, startsect: %d\n", clustnum, startsect); -	while (size > 0) { -		if (size >= FS_BLOCK_SIZE) { -			if (disk_read(startsect + idx, 1, buffer) < 0) { -				FAT_DPRINT("Error reading data\n"); -				return -1; -			} -		} else { -			__u8 tmpbuf[FS_BLOCK_SIZE]; -			if (disk_read(startsect + idx, 1, tmpbuf) < 0) { -				FAT_DPRINT("Error reading data\n"); -				return -1; -			} -			memcpy(buffer, tmpbuf, size); - -			return 0; +	if (disk_read(startsect, size/FS_BLOCK_SIZE , buffer) < 0) { +		FAT_DPRINT("Error reading data\n"); +		return -1; +	} +	if(size % FS_BLOCK_SIZE) { +		__u8 tmpbuf[FS_BLOCK_SIZE]; +		idx= size/FS_BLOCK_SIZE; +		if (disk_read(startsect + idx, 1, tmpbuf) < 0) { +			FAT_DPRINT("Error reading data\n"); +			return -1;  		} -		buffer += FS_BLOCK_SIZE; -		size -= FS_BLOCK_SIZE; -		idx++; +		buffer += idx*FS_BLOCK_SIZE; + +		memcpy(buffer, tmpbuf, size % FS_BLOCK_SIZE); +		return 0;  	}  	return 0; @@ -283,6 +324,8 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,  	unsigned long filesize = FAT2CPU32(dentptr->size), gotsize = 0;  	unsigned int bytesperclust = mydata->clust_size * SECTOR_SIZE;  	__u32 curclust = START(dentptr); +	__u32 endclust, newclust; +	unsigned long actsize;  	FAT_DPRINT("Filesize: %ld bytes\n", filesize); @@ -290,25 +333,56 @@ get_contents(fsdata *mydata, dir_entry *dentptr, __u8 *buffer,  	FAT_DPRINT("Reading: %ld bytes\n", filesize); +	actsize=bytesperclust; +	endclust=curclust;  	do { -		int getsize = (filesize > bytesperclust) ? bytesperclust : -			filesize; - -		if (get_cluster(mydata, curclust, buffer, getsize) != 0) { +		/* search for consecutive clusters */ +		while(actsize < filesize) { +			newclust = get_fatent(mydata, endclust); +			if((newclust -1)!=endclust) +				goto getit; +			if (newclust <= 0x0001 || newclust >= 0xfff0) { +				FAT_DPRINT("curclust: 0x%x\n", newclust); +				FAT_DPRINT("Invalid FAT entry\n"); +				return gotsize; +			} +			endclust=newclust; +			actsize+= bytesperclust; +		} +		/* actsize >= file size */ +		actsize -= bytesperclust; +		/* get remaining clusters */ +		if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) {  			FAT_ERROR("Error reading cluster\n");  			return -1;  		} -		gotsize += getsize; -		filesize -= getsize; -		if (filesize <= 0) return gotsize; -		buffer += getsize; - -		curclust = get_fatent(mydata, curclust); +		/* get remaining bytes */ +		gotsize += (int)actsize; +		filesize -= actsize; +		buffer += actsize; +		actsize= filesize; +		if (get_cluster(mydata, endclust, buffer, (int)actsize) != 0) { +			FAT_ERROR("Error reading cluster\n"); +			return -1; +		} +		gotsize+=actsize; +		return gotsize; +getit: +		if (get_cluster(mydata, curclust, buffer, (int)actsize) != 0) { +			FAT_ERROR("Error reading cluster\n"); +			return -1; +		} +		gotsize += (int)actsize; +		filesize -= actsize; +		buffer += actsize; +		curclust = get_fatent(mydata, endclust);  		if (curclust <= 0x0001 || curclust >= 0xfff0) {  			FAT_DPRINT("curclust: 0x%x\n", curclust);  			FAT_ERROR("Invalid FAT entry\n");  			return gotsize;  		} +		actsize=bytesperclust; +		endclust=curclust;  	} while (1);  } @@ -641,7 +715,7 @@ static long  do_fat_read (const char *filename, void *buffer, unsigned long maxsize,  	     int dols)  { -    __u8 block[FS_BLOCK_SIZE];  /* Block buffer */ +    __u8 block[MAX_CLUSTSIZE];  /* Block buffer */      char fnamecopy[2048];      boot_sector bs;      volume_info volinfo; @@ -713,7 +787,7 @@ do_fat_read (const char *filename, void *buffer, unsigned long maxsize,      while (1) {  	int i; -	if (disk_read (cursect, 1, block) < 0) { +	if (disk_read (cursect, mydata->clust_size, block) < 0) {  	    FAT_DPRINT ("Error: reading rootdir block\n");  	    return -1;  	} @@ -880,8 +954,35 @@ file_fat_detectfs(void)  	boot_sector	bs;  	volume_info	volinfo;  	int		fatsize; +	char	vol_label[12]; -	return read_bootsectandvi(&bs, &volinfo, &fatsize); +	if(cur_dev==NULL) { +		printf("No current device\n"); +		return 1; +	} +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) +	printf("Interface:  "); +	switch(cur_dev->if_type) { +		case IF_TYPE_IDE :	printf("IDE"); break; +		case IF_TYPE_SCSI :	printf("SCSI"); break; +		case IF_TYPE_ATAPI :	printf("ATAPI"); break; +		case IF_TYPE_USB :	printf("USB"); break; +		case IF_TYPE_DOC :	printf("DOC"); break; +		case IF_TYPE_MMC :	printf("MMC"); break; +		default :		printf("Unknown"); +	} +	printf("\n  Device %d: ",cur_dev->dev); +	dev_print(cur_dev); +#endif +	if(read_bootsectandvi(&bs, &volinfo, &fatsize)) { +		printf("\nNo valid FAT fs found\n"); +		return 1; +	} +	memcpy (vol_label, volinfo.volume_label, 11); +	vol_label[11] = '\0'; +	volinfo.fs_type[5]='\0'; +	printf("Partition %d: Filesystem: %s \"%s\"\n",cur_part,volinfo.fs_type,vol_label); +	return 0;  } @@ -895,6 +996,7 @@ file_fat_ls(const char *dir)  long  file_fat_read(const char *filename, void *buffer, unsigned long maxsize)  { +	printf("reading %s\n",filename);  	return do_fat_read(filename, buffer, maxsize, LS_NO);  } diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index 3fd4e52b3..3897ce613 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -1,4 +1,3 @@ -/* vi: set sw=4 ts=4: */  /*  -------------------------------------------------------------------------   * Filename:      jffs2.c @@ -265,20 +264,56 @@ insert_node(struct b_list *list, u32 offset)  }  #ifdef CFG_JFFS2_SORT_FRAGMENTS +/* Sort data entries with the latest version last, so that if there + * is overlapping data the latest version will be used. + */  static int compare_inodes(struct b_node *new, struct b_node *old)  {  	struct jffs2_raw_inode *jNew = (struct jffs2_raw_inode *)new->offset;  	struct jffs2_raw_inode *jOld = (struct jffs2_raw_inode *)old->offset; -	return jNew->version < jOld->version; +	return jNew->version > jOld->version;  } +/* Sort directory entries so all entries in the same directory + * with the same name are grouped together, with the latest version + * last. This makes it easy to eliminate all but the latest version + * by marking the previous version dead by setting the inode to 0. + */  static int compare_dirents(struct b_node *new, struct b_node *old)  {  	struct jffs2_raw_dirent *jNew = (struct jffs2_raw_dirent *)new->offset;  	struct jffs2_raw_dirent *jOld = (struct jffs2_raw_dirent *)old->offset; +	int cmp; -	return jNew->version > jOld->version; +	/* ascending sort by pino */ +	if (jNew->pino != jOld->pino) +		return jNew->pino > jOld->pino; + +	/* pino is the same, so use ascending sort by nsize, so +	 * we don't do strncmp unless we really must. +	 */ +	if (jNew->nsize != jOld->nsize) +		return jNew->nsize > jOld->nsize; + +	/* length is also the same, so use ascending sort by name +	 */ +	cmp = strncmp(jNew->name, jOld->name, jNew->nsize); +	if (cmp != 0) +		return cmp > 0; + +	/* we have duplicate names in this directory, so use ascending +	 * sort by version +	 */ +	if (jNew->version > jOld->version) { +		/* since jNew is newer, we know jOld is not valid, so +		 * mark it with inode 0 and it will not be used +		 */ +		jOld->ino = 0; +		return 1; +	} +	 +	return 0;  }  #endif @@ -327,12 +362,31 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)  	struct b_node *b;  	struct jffs2_raw_inode *jNode;  	u32 totalSize = 0; -	u16 latestVersion = 0; +	u32 latestVersion = 0;  	char *lDest;  	char *src;  	long ret;  	int i;  	u32 counter = 0; +#ifdef CFG_JFFS2_SORT_FRAGMENTS +	/* Find file size before loading any data, so fragments that +	 * start past the end of file can be ignored. A fragment +	 * that is partially in the file is loaded, so extra data may +	 * be loaded up to the next 4K boundary above the file size. +	 * This shouldn't cause trouble when loading kernel images, so +	 * we will live with it. +	 */ +	for (b = pL->frag.listHead; b != NULL; b = b->next) { +		jNode = (struct jffs2_raw_inode *) (b->offset); +		if ((inode == jNode->ino)) { +			/* get actual file length from the newest node */ +			if (jNode->version >= latestVersion) { +				totalSize = jNode->isize; +				latestVersion = jNode->version; +			} +		} +	} +#endif  	for (b = pL->frag.listHead; b != NULL; b = b->next) {  		jNode = (struct jffs2_raw_inode *) (b->offset); @@ -349,11 +403,14 @@ jffs2_1pass_read_inode(struct b_lists *pL, u32 inode, char *dest)  			putLabeledWord("read_inode: usercompr = ", jNode->usercompr);  			putLabeledWord("read_inode: flags = ", jNode->flags);  #endif + +#ifndef CFG_JFFS2_SORT_FRAGMENTS  			/* get actual file length from the newest node */  			if (jNode->version >= latestVersion) {  				totalSize = jNode->isize;  				latestVersion = jNode->version;  			} +#endif  			if(dest) {  				src = ((char *) jNode) + sizeof(struct jffs2_raw_inode); @@ -430,15 +487,11 @@ jffs2_1pass_find_inode(struct b_lists * pL, const char *name, u32 pino)  		if ((pino == jDir->pino) && (len == jDir->nsize) &&  		    (jDir->ino) &&	/* 0 for unlink */  		    (!strncmp(jDir->name, name, len))) {	/* a match */ -			if (jDir->version < version) continue; +			if (jDir->version < version) +				continue; -		        if(jDir->version == 0) { -			    	/* Is this legal? */ -				putstr(" ** WARNING ** "); -				putnstr(jDir->name, jDir->nsize); -				putstr(" is version 0 (in find, ignoring)\r\n"); -			} else if(jDir->version == version) { -			    	/* Im pretty sure this isn't ... */ +			if (jDir->version == version && inode != 0) { +			    	/* I'm pretty sure this isn't legal */  				putstr(" ** ERROR ** ");  				putnstr(jDir->name, jDir->nsize);  				putLabeledWord(" has dup version =", version); @@ -643,15 +696,11 @@ jffs2_1pass_resolve_inode(struct b_lists * pL, u32 ino)  	for(b = pL->dir.listHead; b; b = b->next) {  		jDir = (struct jffs2_raw_dirent *) (b->offset);  		if (ino == jDir->ino) { -		    	if(jDir->version < version) continue; +		    	if (jDir->version < version) +				continue; -			if(jDir->version == 0) { -			    	/* Is this legal? */ -				putstr(" ** WARNING ** "); -				putnstr(jDir->name, jDir->nsize); -				putstr(" is version 0 (in resolve, ignoring)\r\n"); -			} else if(jDir->version == version) { -			    	/* Im pretty sure this isn't ... */ +			if (jDir->version == version && jDirFound) { +			    	/* I'm pretty sure this isn't legal */  				putstr(" ** ERROR ** ");  				putnstr(jDir->name, jDir->nsize);  				putLabeledWord(" has dup version (resolve) = ", @@ -891,6 +940,11 @@ jffs2_1pass_build_lists(struct part_info * part)  					printf("OOPS Cleanmarker has bad size "  						"%d != %d\n", node->totlen,  						sizeof(struct jffs2_unknown_node)); +			} else if (node->nodetype == JFFS2_NODETYPE_PADDING) { +				if (node->totlen < sizeof(struct jffs2_unknown_node)) +					printf("OOPS Padding has bad size " +						"%d < %d\n", node->totlen, +						sizeof(struct jffs2_unknown_node));  			} else {  				printf("Unknown node type: %x len %d "  					"offset 0x%x\n", node->nodetype, diff --git a/include/configs/AdderII.h b/include/configs/AdderII.h index c2cff23a1..4c2ba7d58 100644 --- a/include/configs/AdderII.h +++ b/include/configs/AdderII.h @@ -48,10 +48,10 @@  #define CONFIG_CLOCKS_IN_MHZ	1  /* Monitor Functions */ -#define CONFIG_COMMANDS		( CFG_CMD_FLASH | \ +#define CONFIG_COMMANDS		( CFG_CMD_ENV	| \ +				  CFG_CMD_FLASH | \  				  CFG_CMD_MEMORY| \  				  CFG_CMD_NET   | \ -				  CFG_CMD_ENV	| \  				  CFG_CMD_PING  | \  				  CFG_CMD_SDRAM ) diff --git a/include/configs/MIP405.h b/include/configs/MIP405.h index 49b830b86..61a799daa 100644 --- a/include/configs/MIP405.h +++ b/include/configs/MIP405.h @@ -67,6 +67,7 @@  			CFG_CMD_DATE	| \  			CFG_CMD_ELF	| \  			CFG_CMD_MII	| \ +			CFG_CMD_FAT | \  			CFG_CMD_PING	| \  			CFG_CMD_SAVES	| \  			CFG_CMD_BSP	) @@ -246,9 +247,10 @@  /*   * Init Memory Controller:   */ - -#define FLASH_BASE0_PRELIM	0xFFC00000	/* FLASH bank #0	*/ -#define FLASH_BASE1_PRELIM	0		/* FLASH bank #1	*/ +#define FLASH_MAX_SIZE		0x00800000		/* 8MByte max */ +#define FLASH_BASE_PRELIM	0xFF800000  /* open the flash CS */ +/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ +#define FLASH_SIZE_PRELIM	 3  /* maximal flash FLASH size bank #0	*/  #define CONFIG_BOARD_PRE_INIT @@ -325,7 +327,7 @@  #undef	CONFIG_IDE_LED	       /* no led for ide supported     */  #define CONFIG_IDE_RESET       /* reset for ide supported...	*/  #define CONFIG_IDE_RESET_ROUTINE /* with a special reset function */ - +#define CONFIG_SUPPORT_VFAT  /************************************************************   * ATAPI support (experimental)   ************************************************************/ diff --git a/include/configs/PIP405.h b/include/configs/PIP405.h index d9f8be8ee..b9107ccf7 100644 --- a/include/configs/PIP405.h +++ b/include/configs/PIP405.h @@ -50,11 +50,13 @@  			CFG_CMD_PCI	| \  			CFG_CMD_CACHE	| \  			CFG_CMD_IRQ	| \ +			CFG_CMD_ECHO	| \  			CFG_CMD_EEPROM	| \  			CFG_CMD_I2C	| \  			CFG_CMD_REGINFO | \  			CFG_CMD_FDC	| \  			CFG_CMD_SCSI	| \ +			CFG_CMD_FAT 	| \  			CFG_CMD_DATE	| \  			CFG_CMD_ELF	| \  			CFG_CMD_USB	| \ @@ -141,7 +143,7 @@  #define CONFIG_LOADS_ECHO	1	/* echo on for serial download	*/  #define CFG_LOADS_BAUD_CHANGE	1	/* allow baudrate change	*/ - +#define CONFIG_MISC_INIT_R  /***********************************************************   * Miscellaneous configurable options   **********************************************************/ @@ -231,9 +233,12 @@  /*   * Init Memory Controller:   */ +#define FLASH_MAX_SIZE		0x00800000		/* 8MByte max */ +#define FLASH_BASE_PRELIM	0xFF800000  /* open the flash CS */ +/* Size: 0=1MB, 1=2MB, 2=4MB, 3=8MB, 4=16MB, 5=32MB, 6=64MB, 7=128MB */ +#define FLASH_SIZE_PRELIM	 3  /* maximal flash FLASH size bank #0	*/ -#define FLASH_BASE0_PRELIM	0xFFC00000	/* FLASH bank #0	*/ -#define FLASH_BASE1_PRELIM	0		/* FLASH bank #1	*/ +#define CONFIG_BOARD_PRE_INIT  /* Configuration Port location */  #define CONFIG_PORT_ADDR	0xF4000000 @@ -299,6 +304,7 @@  #undef	CONFIG_IDE_LED			/* no led for ide supported	*/  #define CONFIG_IDE_RESET		/* reset for ide supported...	*/  #define CONFIG_IDE_RESET_ROUTINE	/* with a special reset function */ +#define CONFIG_SUPPORT_VFAT  /************************************************************   * ATAPI support (experimental) diff --git a/include/configs/SXNI855T.h b/include/configs/SXNI855T.h index bdaf683c3..d6fa79807 100644 --- a/include/configs/SXNI855T.h +++ b/include/configs/SXNI855T.h @@ -145,12 +145,22 @@  #define CONFIG_COMMANDS		(CONFIG_CMD_DFL		| \  				 CFG_CMD_EEPROM		| \ +				 CFG_CMD_JFFS2		| \  				 CFG_CMD_NAND		| \  				 CFG_CMD_DATE)  /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */  #include <cmd_confdefs.h> +#define CFG_JFFS_CUSTOM_PART +#define CFG_JFFS2_SORT_FRAGMENTS +/* JFFS2 location when using NOR flash */ +#define CFG_JFFS2_BASE	(CFG_FLASH_BASE + 0x80000) +#define CFG_JFFS2_SIZE	(0x780000) +/* JFFS2 location (in RAM) when using NAND flash */ +#define	CFG_JFFS2_RAMBASE 0x400000 +#define	CFG_JFFS2_RAMSIZE 0x200000	/* NAND boot partition is 2MiB	*/ +  /* NAND flash support */  #define CONFIG_MTD_NAND_ECC_JFFS2  #define CFG_MAX_NAND_DEVICE	1	/* Max number of NAND devices	*/ @@ -405,13 +415,18 @@  #define CONFIG_RESET_ON_PANIC		/* reset if system panic() */ -/* to put environment in EEROM */ -#define	CFG_ENV_IS_IN_EEPROM	1 -#define CFG_ENV_OFFSET		0	/* Start right at beginning of NVRAM */ -#define CFG_ENV_SIZE		1024	/* Use only a part of it*/ - -#if 1 -#define CONFIG_BOOT_RETRY_TIME	60	/* boot if no command in 60 seconds */ +#define CFG_ENV_IS_IN_FLASH +#ifdef CFG_ENV_IS_IN_FLASH +  /* environment is in FLASH */ +  #define CFG_ENV_ADDR		0xF8040000	/* AM29LV641 or AM29LV800BT */ +  #define CFG_ENV_ADDR_REDUND	0xF8050000	/* AM29LV641 or AM29LV800BT */ +  #define CFG_ENV_SECT_SIZE	0x00010000 +  #define CFG_ENV_SIZE		0x00002000 +#else +  /* environment is in EEPROM */ +  #define CFG_ENV_IS_IN_EEPROM		1 +  #define CFG_ENV_OFFSET		0	/* at beginning of EEPROM */ +  #define CFG_ENV_SIZE		     1024	/* Use only a part of it*/  #endif  #if 1 diff --git a/include/fat.h b/include/fat.h index b56219ced..6f0f40fa6 100644 --- a/include/fat.h +++ b/include/fat.h @@ -204,5 +204,6 @@ int file_fat_detectfs(void);  int file_fat_ls(const char *dir);  long file_fat_read(const char *filename, void *buffer, unsigned long maxsize);  const char *file_getfsname(int idx); +int fat_register_device(block_dev_desc_t *dev_desc, int part_no);  #endif /* _FAT_H_ */ diff --git a/include/jffs2/jffs2.h b/include/jffs2/jffs2.h index fc3a8419a..4bdc525ce 100644 --- a/include/jffs2/jffs2.h +++ b/include/jffs2/jffs2.h @@ -82,6 +82,7 @@  #define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)  #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)  #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) +#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)  /* Maybe later... */  /*#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) */ diff --git a/include/part.h b/include/part.h index 2f5a01dea..c24f90920 100644 --- a/include/part.h +++ b/include/part.h @@ -50,6 +50,7 @@ typedef struct block_dev_desc {  #define IF_TYPE_ATAPI		3  #define IF_TYPE_USB		4  #define IF_TYPE_DOC		5 +#define IF_TYPE_MMC		6  /* Part types */  #define	PART_TYPE_UNKNOWN	0x00 diff --git a/post/cache_8xx.S b/post/cache_8xx.S index 2974882b8..2d41b5566 100644 --- a/post/cache_8xx.S +++ b/post/cache_8xx.S @@ -27,8 +27,7 @@      defined(CONFIG_MPC850) || \      defined(CONFIG_MPC855) || \      defined(CONFIG_MPC860) || \ -    defined(CONFIG_MPC862) || \ -    defined(CONFIG_MPC824X) +    defined(CONFIG_MPC862)  #include <post.h>  #include <ppc_asm.tmpl> @@ -491,6 +490,6 @@ cache_post_test6_data:  	mtlr	r0  	blr -#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 || MPC824X */ +#endif /* CONFIG_MPC823 || MPC850 || MPC855 || MPC860 */  #endif /* CONFIG_POST & CFG_POST_CACHE */  #endif /* CONFIG_POST */ diff --git a/post/ether.c b/post/ether.c index d174ad1c0..0a8b36fca 100644 --- a/post/ether.c +++ b/post/ether.c @@ -38,7 +38,7 @@  #ifdef CONFIG_POST  #include <post.h> - +#if CONFIG_POST & CFG_POST_ETHER  #if defined(CONFIG_8xx)  #include <commproc.h>  #elif defined(CONFIG_MPC8260) @@ -50,8 +50,6 @@  #include <command.h>  #include <net.h> -#if CONFIG_POST & CFG_POST_ETHER -  #define MIN_PACKET_LENGTH	64  #define MAX_PACKET_LENGTH	256  #define TEST_NUM		1 diff --git a/post/uart.c b/post/uart.c index 3eaafd820..15df74eef 100644 --- a/post/uart.c +++ b/post/uart.c @@ -39,6 +39,7 @@  #ifdef CONFIG_POST  #include <post.h> +#if CONFIG_POST & CFG_POST_UART  #if defined(CONFIG_8xx)  #include <commproc.h>  #elif defined(CONFIG_MPC8260) @@ -49,8 +50,6 @@  #include <command.h>  #include <net.h> -#if CONFIG_POST & CFG_POST_UART -  #define CTLR_SMC 0  #define CTLR_SCC 1 |