diff options
Diffstat (limited to 'roms/u-boot/board/esd/common')
22 files changed, 5052 insertions, 0 deletions
diff --git a/roms/u-boot/board/esd/common/auto_update.c b/roms/u-boot/board/esd/common/auto_update.c new file mode 100644 index 00000000..85c3567b --- /dev/null +++ b/roms/u-boot/board/esd/common/auto_update.c @@ -0,0 +1,484 @@ +/* + * (C) Copyright 2003-2004 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de. + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#include <command.h> +#include <image.h> +#include <asm/byteorder.h> +#include <fat.h> +#include <part.h> + +#include "auto_update.h" + +#ifdef CONFIG_AUTO_UPDATE + +#if !defined(CONFIG_CMD_FAT) +#error "must define CONFIG_CMD_FAT" +#endif + +extern au_image_t au_image[]; +extern int N_AU_IMAGES; + +/* where to load files into memory */ +#define LOAD_ADDR ((unsigned char *)0x100000) +#define MAX_LOADSZ 0x1c00000 + +/* externals */ +extern int fat_register_device(block_dev_desc_t *, int); +extern int file_fat_detectfs(void); +extern long file_fat_read(const char *, void *, unsigned long); +long do_fat_read (const char *filename, void *buffer, +		  unsigned long maxsize, int dols); +extern int flash_sect_erase(ulong, ulong); +extern int flash_sect_protect (int, ulong, ulong); +extern int flash_write (char *, ulong, ulong); + +extern block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; + +int au_check_cksum_valid(int i, long nbytes) +{ +	image_header_t *hdr; + +	hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) +	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { +		puts ("Non legacy image format not supported\n"); +		return -1; +	} +#endif + +	if ((au_image[i].type == AU_FIRMWARE) && +	    (au_image[i].size != image_get_data_size (hdr))) { +		printf ("Image %s has wrong size\n", au_image[i].name); +		return -1; +	} + +	if (nbytes != (image_get_image_size (hdr))) { +		printf ("Image %s bad total SIZE\n", au_image[i].name); +		return -1; +	} + +	/* check the data CRC */ +	if (!image_check_dcrc (hdr)) { +		printf ("Image %s bad data checksum\n", au_image[i].name); +		return -1; +	} +	return 0; +} + +int au_check_header_valid(int i, long nbytes) +{ +	image_header_t *hdr; + +	hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) +	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { +		puts ("Non legacy image format not supported\n"); +		return -1; +	} +#endif + +	/* check the easy ones first */ +	if (nbytes < image_get_header_size ()) { +		printf ("Image %s bad header SIZE\n", au_image[i].name); +		return -1; +	} +	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) { +		printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name); +		return -1; +	} +	if (!image_check_hcrc (hdr)) { +		printf ("Image %s bad header checksum\n", au_image[i].name); +		return -1; +	} + +	/* check the type - could do this all in one gigantic if() */ +	if (((au_image[i].type & AU_TYPEMASK) == AU_FIRMWARE) && +	    !image_check_type (hdr, IH_TYPE_FIRMWARE)) { +		printf ("Image %s wrong type\n", au_image[i].name); +		return -1; +	} +	if (((au_image[i].type & AU_TYPEMASK) == AU_SCRIPT) && +	    !image_check_type (hdr, IH_TYPE_SCRIPT)) { +		printf ("Image %s wrong type\n", au_image[i].name); +		return -1; +	} + +	return 0; +} + +int au_do_update(int i, long sz) +{ +	image_header_t *hdr; +	char *addr; +	long start, end; +	int off, rc; +	uint nbytes; +	int k; + +	hdr = (image_header_t *)LOAD_ADDR; +#if defined(CONFIG_FIT) +	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { +		puts ("Non legacy image format not supported\n"); +		return -1; +	} +#endif + +	switch (au_image[i].type & AU_TYPEMASK) { +	case AU_SCRIPT: +		printf("Executing script %s\n", au_image[i].name); + +		/* execute a script */ +		if (image_check_type (hdr, IH_TYPE_SCRIPT)) { +			addr = (char *)((char *)hdr + image_get_header_size ()); +			/* stick a NULL at the end of the script, otherwise */ +			/* parse_string_outer() runs off the end. */ +			addr[image_get_data_size (hdr)] = 0; +			addr += 8; + +			/* +			 * Replace cr/lf with ; +			 */ +			k = 0; +			while (addr[k] != 0) { +				if ((addr[k] == 10) || (addr[k] == 13)) { +					addr[k] = ';'; +				} +				k++; +			} + +			run_command(addr, 0); +			return 0; +		} + +		break; + +	case AU_FIRMWARE: +	case AU_NOR: +	case AU_NAND: +		start = au_image[i].start; +		end = au_image[i].start + au_image[i].size - 1; + +		/* +		 * do not update firmware when image is already in flash. +		 */ +		if (au_image[i].type == AU_FIRMWARE) { +			char *orig = (char*)start; +			char *new  = (char *)((char *)hdr + +					      image_get_header_size ()); +			nbytes = image_get_data_size (hdr); + +			while (--nbytes) { +				if (*orig++ != *new++) { +					break; +				} +			} +			if (!nbytes) { +				printf ("Skipping firmware update - " +					"images are identical\n"); +				break; +			} +		} + +		/* unprotect the address range */ +		if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) || +		    (au_image[i].type == AU_FIRMWARE)) { +			flash_sect_protect (0, start, end); +		} + +		/* +		 * erase the address range. +		 */ +		if (au_image[i].type != AU_NAND) { +			printf ("Updating NOR FLASH with image %s\n", +				au_image[i].name); +			debug ("flash_sect_erase(%lx, %lx);\n", start, end); +			flash_sect_erase (start, end); +		} + +		udelay(10000); + +		/* strip the header - except for the kernel and ramdisk */ +		if (au_image[i].type != AU_FIRMWARE) { +			addr = (char *)hdr; +			off = image_get_header_size (); +			nbytes = image_get_image_size (hdr); +		} else { +			addr = (char *)((char *)hdr + image_get_header_size ()); +			off = 0; +			nbytes = image_get_data_size (hdr); +		} + +		/* +		 * copy the data from RAM to FLASH +		 */ +		if (au_image[i].type != AU_NAND) { +			debug ("flash_write(%p, %lx, %x)\n", +			       addr, start, nbytes); +			rc = flash_write ((char *)addr, start, +					  (nbytes + 1) & ~1); +		} else { +			rc = -1; +		} +		if (rc != 0) { +			printf ("Flashing failed due to error %d\n", rc); +			return -1; +		} + +		/* +		 * check the dcrc of the copy +		 */ +		if (au_image[i].type != AU_NAND) { +			rc = crc32 (0, (uchar *)(start + off), +				    image_get_data_size (hdr)); +		} +		if (rc != image_get_dcrc (hdr)) { +			printf ("Image %s Bad Data Checksum After COPY\n", +				au_image[i].name); +			return -1; +		} + +		/* protect the address range */ +		/* this assumes that ONLY the firmware is protected! */ +		if (((au_image[i].type & AU_FLAGMASK) == AU_PROTECT) || +		    (au_image[i].type == AU_FIRMWARE)) { +			flash_sect_protect (1, start, end); +		} + +		break; + +	default: +		printf("Wrong image type selected!\n"); +	} + +	return 0; +} + +static void process_macros (const char *input, char *output) +{ +	char c, prev; +	const char *varname_start = NULL; +	int inputcnt  = strlen (input); +	int outputcnt = CONFIG_SYS_CBSIZE; +	int state = 0;	/* 0 = waiting for '$'	*/ +			/* 1 = waiting for '(' or '{' */ +			/* 2 = waiting for ')' or '}' */ +			/* 3 = waiting for '''  */ +#ifdef DEBUG_PARSER +	char *output_start = output; + +	printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", +		strlen(input), input); +#endif + +	prev = '\0';			/* previous character */ + +	while (inputcnt && outputcnt) { +	    c = *input++; +	    inputcnt--; + +	    if (state != 3) { +	    /* remove one level of escape characters */ +	    if ((c == '\\') && (prev != '\\')) { +		if (inputcnt-- == 0) +			break; +		prev = c; +		c = *input++; +	    } +	    } + +	    switch (state) { +	    case 0:			/* Waiting for (unescaped) $ */ +		if ((c == '\'') && (prev != '\\')) { +			state = 3; +			break; +		} +		if ((c == '$') && (prev != '\\')) { +			state++; +		} else { +			*(output++) = c; +			outputcnt--; +		} +		break; +	    case 1:			/* Waiting for ( */ +		if (c == '(' || c == '{') { +			state++; +			varname_start = input; +		} else { +			state = 0; +			*(output++) = '$'; +			outputcnt--; + +			if (outputcnt) { +				*(output++) = c; +				outputcnt--; +			} +		} +		break; +	    case 2:			/* Waiting for )	*/ +		if (c == ')' || c == '}') { +			int i; +			char envname[CONFIG_SYS_CBSIZE], *envval; +			/* Varname # of chars */ +			int envcnt = input - varname_start - 1; + +			/* Get the varname */ +			for (i = 0; i < envcnt; i++) { +				envname[i] = varname_start[i]; +			} +			envname[i] = 0; + +			/* Get its value */ +			envval = getenv (envname); + +			/* Copy into the line if it exists */ +			if (envval != NULL) +				while ((*envval) && outputcnt) { +					*(output++) = *(envval++); +					outputcnt--; +				} +			/* Look for another '$' */ +			state = 0; +		} +		break; +	    case 3:			/* Waiting for '	*/ +		if ((c == '\'') && (prev != '\\')) { +			state = 0; +		} else { +			*(output++) = c; +			outputcnt--; +		} +		break; +	    } +	    prev = c; +	} + +	if (outputcnt) +		*output = 0; + +#ifdef DEBUG_PARSER +	printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n", +		strlen (output_start), output_start); +#endif +} + +/* + * this is called from board_init() after the hardware has been set up + * and is usable. That seems like a good time to do this. + * Right now the return value is ignored. + */ +int do_auto_update(void) +{ +	block_dev_desc_t *stor_dev = NULL; +	long sz; +	int i, res, cnt, old_ctrlc; +	char buffer[32]; +	char str[80]; +	int n; + +	if  (ide_dev_desc[0].type != DEV_TYPE_UNKNOWN) { +		stor_dev = get_dev ("ide", 0); +		if (stor_dev == NULL) { +			debug ("ide: unknown device\n"); +			return -1; +		} +	} + +	if (fat_register_device (stor_dev, 1) != 0) { +		debug ("Unable to register ide disk 0:1\n"); +		return -1; +	} + +	/* +	 * Check if magic file is present +	 */ +	if ((n = do_fat_read (AU_MAGIC_FILE, buffer, +			      sizeof(buffer), LS_NO)) <= 0) { +		debug ("No auto_update magic file (n=%d)\n", n); +		return -1; +	} + +#ifdef CONFIG_AUTO_UPDATE_SHOW +	board_auto_update_show (1); +#endif +	puts("\nAutoUpdate Disk detected! Trying to update system...\n"); + +	/* make sure that we see CTRL-C and save the old state */ +	old_ctrlc = disable_ctrlc (0); + +	/* just loop thru all the possible files */ +	for (i = 0; i < N_AU_IMAGES; i++) { +		/* +		 * Try to expand the environment var in the fname +		 */ +		process_macros (au_image[i].name, str); +		strcpy (au_image[i].name, str); + +		printf("Reading %s ...", au_image[i].name); +		/* just read the header */ +		sz = do_fat_read (au_image[i].name, LOAD_ADDR, +				  image_get_header_size (), LS_NO); +		debug ("read %s sz %ld hdr %d\n", +			au_image[i].name, sz, image_get_header_size ()); +		if (sz <= 0 || sz < image_get_header_size ()) { +			puts(" not found\n"); +			continue; +		} +		if (au_check_header_valid (i, sz) < 0) { +			puts(" header not valid\n"); +			continue; +		} +		sz = do_fat_read (au_image[i].name, LOAD_ADDR, +				  MAX_LOADSZ, LS_NO); +		debug ("read %s sz %ld hdr %d\n", +			au_image[i].name, sz, image_get_header_size ()); +		if (sz <= 0 || sz <= image_get_header_size ()) { +			puts(" not found\n"); +			continue; +		} +		if (au_check_cksum_valid (i, sz) < 0) { +			puts(" checksum not valid\n"); +			continue; +		} +		puts(" done\n"); + +		do { +			res = au_do_update (i, sz); +			/* let the user break out of the loop */ +			if (ctrlc() || had_ctrlc ()) { +				clear_ctrlc (); +				break; +			} +			cnt++; +		} while (res < 0); +	} + +	/* restore the old state */ +	disable_ctrlc (old_ctrlc); + +	puts("AutoUpdate finished\n\n"); +#ifdef CONFIG_AUTO_UPDATE_SHOW +	board_auto_update_show (0); +#endif + +	return 0; +} + +int auto_update(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	do_auto_update(); + +	return 0; +} +U_BOOT_CMD( +	autoupd,	1,	1,	auto_update, +	"Automatically update images", +	"" +); +#endif /* CONFIG_AUTO_UPDATE */ diff --git a/roms/u-boot/board/esd/common/auto_update.h b/roms/u-boot/board/esd/common/auto_update.h new file mode 100644 index 00000000..be8f439e --- /dev/null +++ b/roms/u-boot/board/esd/common/auto_update.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef _AUTO_UPDATE_H_ +#define _AUTO_UPDATE_H_ + +#define MBR_MAGIC       0x07081967 +#define MBR_MAGIC_ADDR  0x100           /* offset 0x100 should be free space */ + +#define AU_MAGIC_FILE   "__auto_update" + +#define AU_TYPEMASK     0x000000ff +#define AU_FLAGMASK     0xffff0000 + +#define AU_PROTECT      0x80000000 + +#define AU_SCRIPT       0x01 +#define AU_FIRMWARE     (0x02 | AU_PROTECT) +#define AU_NOR          0x03 +#define AU_NAND         0x04 + +struct au_image_s { +	char name[80]; +	ulong start; +	ulong size; +	ulong type; +}; + +typedef struct au_image_s au_image_t; + +int do_auto_update(void); +#ifdef CONFIG_AUTO_UPDATE_SHOW +void board_auto_update_show(int au_active); +#endif + +#endif /* #ifndef _AUTO_UPDATE_H_ */ diff --git a/roms/u-boot/board/esd/common/cmd_loadpci.c b/roms/u-boot/board/esd/common/cmd_loadpci.c new file mode 100644 index 00000000..803179a4 --- /dev/null +++ b/roms/u-boot/board/esd/common/cmd_loadpci.c @@ -0,0 +1,113 @@ +/* + * (C) Copyright 2005-2008 + * Matthias Fuchs, esd GmbH Germany, matthias.fuchs@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#if !defined(CONFIG_440) +#include <asm/4xx_pci.h> +#endif + +#if defined(CONFIG_CMD_BSP) + +extern int do_source (cmd_tbl_t *, int, int, char *[]); + +#define ADDRMASK 0xfffff000 + +/* + * Command loadpci: wait for signal from host and boot image. + */ +int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	u32 *ptr = 0; +	int count = 0; +	int count2 = 0; +	char addr[16]; +	char str[] = "\\|/-"; +	char *local_args[2]; +	u32 la, ptm1la; + +#if defined(CONFIG_440) +	ptm1la = in32r(PCIL0_PTM1LA); +#else +	ptm1la = in32r(PTM1LA); +#endif +	while(1) { +		/* +		 * Mark sync address +		 */ +		ptr = (u32 *)ptm1la; +		memset(ptr, 0, 0x20); + +		*ptr = 0xffffffff; +		puts("\nWaiting for action from pci host -"); + +		/* +		 * Wait for host to write the start address +		 */ +		while (*ptr == 0xffffffff) { +			count++; +			if (!(count % 100)) { +				count2++; +				putc(0x08); /* backspace */ +				putc(str[count2 % 4]); +			} + +			/* Abort if ctrl-c was pressed */ +			if (ctrlc()) { +				puts("\nAbort\n"); +				return 0; +			} + +			udelay(1000); +		} + +		printf("\nGot bootcode %08x: ", *ptr); +		la = ptm1la + (*ptr & ADDRMASK); +		sprintf(addr, "%08x", la); + +		switch (*ptr & ~ADDRMASK) { +		case 0: +			/* +			 * Boot image via bootm +			 */ +			printf("booting image at addr 0x%s ...\n", addr); +			setenv("loadaddr", addr); +			do_bootm(cmdtp, 0, 0, NULL); +			break; + +		case 1: +			/* +			 * Boot image via "source" command +			 */ +			printf("executing script at addr 0x%s ...\n", addr); +			local_args[0] = addr; +			local_args[1] = NULL; +			do_source(cmdtp, 0, 1, local_args); +			break; + +		case 2: +			/* +			 * Call run_cmd +			 */ +			printf("running command at addr 0x%s ...\n", addr); +			run_command((char *)la, 0); +			break; + +		default: +			printf("unhandled boot method\n"); +			break; +		} +	} +} + +U_BOOT_CMD( +	loadpci,	1,	1,	do_loadpci, +	"Wait for pci bootcmd and boot it", +	"" +); + +#endif diff --git a/roms/u-boot/board/esd/common/esd405ep_nand.c b/roms/u-boot/board/esd/common/esd405ep_nand.c new file mode 100644 index 00000000..f46936ca --- /dev/null +++ b/roms/u-boot/board/esd/common/esd405ep_nand.c @@ -0,0 +1,69 @@ +/* + * (C) Copyright 2007 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#if defined(CONFIG_CMD_NAND) +#include <asm/io.h> +#include <nand.h> + +/* + * hardware specific access to control-lines + */ +static void esd405ep_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ +	struct nand_chip *this = mtd->priv; +	if (ctrl & NAND_CTRL_CHANGE) { +		if ( ctrl & NAND_CLE ) +			out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_CLE); +		else +			out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_NAND_CLE); +		if ( ctrl & NAND_ALE ) +			out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_ALE); +		else +			out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_NAND_ALE); +		if ( ctrl & NAND_NCE ) +			out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_NAND_CE); +		else +			out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_CE); +	} + +	if (cmd != NAND_CMD_NONE) +		writeb(cmd, this->IO_ADDR_W); +} + + +/* + * read device ready pin + */ +static int esd405ep_nand_device_ready(struct mtd_info *mtdinfo) +{ +	if (in_be32((void *)GPIO0_IR) & CONFIG_SYS_NAND_RDY) +		return 1; +	return 0; +} + + +int board_nand_init(struct nand_chip *nand) +{ +	/* +	 * Set NAND-FLASH GPIO signals to defaults +	 */ +	out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) & ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE)); +	out_be32((void *)GPIO0_OR, in_be32((void *)GPIO0_OR) | CONFIG_SYS_NAND_CE); + +	/* +	 * Initialize nand_chip structure +	 */ +	nand->cmd_ctrl = esd405ep_nand_hwcontrol; +	nand->dev_ready = esd405ep_nand_device_ready; +	nand->ecc.mode = NAND_ECC_SOFT; +	nand->chip_delay = NAND_BIG_DELAY_US; +	nand->options = NAND_SAMSUNG_LP_OPTIONS; +	return 0; +} +#endif diff --git a/roms/u-boot/board/esd/common/flash.c b/roms/u-boot/board/esd/common/flash.c new file mode 100644 index 00000000..e3512c78 --- /dev/null +++ b/roms/u-boot/board/esd/common/flash.c @@ -0,0 +1,659 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#ifdef __PPC__ +#include <asm/ppc4xx.h> +#endif +#include <asm/processor.h> + +flash_info_t	flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips	*/ + +/*----------------------------------------------------------------------- + * Functions + */ +static int write_word (flash_info_t *info, ulong dest, ulong data); + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ +	int i; +	short n; + +	/* set up sector start address table */ +	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) { +	    for (i = 0; i < info->sector_count; i++) +		info->start[i] = base + (i * 0x00010000); +	} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) { +		/* set sector offsets for bottom boot block type	*/ +		for (i=0; i<8; ++i) {		/*  8 x 8k boot sectors	*/ +			info->start[i] = base; +			base += 8 << 10; +		} +		while (i < info->sector_count) {	/* 64k regular sectors	*/ +			info->start[i] = base; +			base += 64 << 10; +			++i; +		} +	} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) { +		/* set sector offsets for top boot block type		*/ +		base += info->size; +		i = info->sector_count; +		for (n=0; n<8; ++n) {		/*  8 x 8k boot sectors	*/ +			base -= 8 << 10; +			--i; +			info->start[i] = base; +		} +		while (i > 0) {			/* 64k regular sectors	*/ +			base -= 64 << 10; +			--i; +			info->start[i] = base; +		} +	} else { +	    if (info->flash_id & FLASH_BTYPE) { +		/* set sector offsets for bottom boot block type	*/ +		info->start[0] = base + 0x00000000; +		info->start[1] = base + 0x00004000; +		info->start[2] = base + 0x00006000; +		info->start[3] = base + 0x00008000; +		for (i = 4; i < info->sector_count; i++) { +			info->start[i] = base + (i * 0x00010000) - 0x00030000; +		} +	    } else { +		/* set sector offsets for top boot block type		*/ +		i = info->sector_count - 1; +		info->start[i--] = base + info->size - 0x00004000; +		info->start[i--] = base + info->size - 0x00006000; +		info->start[i--] = base + info->size - 0x00008000; +		for (; i >= 0; i--) { +			info->start[i] = base + i * 0x00010000; +		} +	    } +	} +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info  (flash_info_t *info) +{ +	int i; +	int k; +	int size; +	int erased; +	volatile unsigned long *flash; + +	if (info->flash_id == FLASH_UNKNOWN) { +		printf ("missing or unknown FLASH type\n"); +		return; +	} + +	switch (info->flash_id & FLASH_VENDMASK) { +	case FLASH_MAN_AMD:	printf ("AMD ");		break; +	case FLASH_MAN_FUJ:	printf ("FUJITSU ");		break; +	case FLASH_MAN_SST:	printf ("SST ");		break; +	case FLASH_MAN_EXCEL:	printf ("Excel Semiconductor "); break; +	default:		printf ("Unknown Vendor ");	break; +	} + +	switch (info->flash_id & FLASH_TYPEMASK) { +	case FLASH_AM400B:	printf ("AM29LV400B (4 Mbit, bottom boot sect)\n"); +				break; +	case FLASH_AM400T:	printf ("AM29LV400T (4 Mbit, top boot sector)\n"); +				break; +	case FLASH_AM800B:	printf ("AM29LV800B (8 Mbit, bottom boot sect)\n"); +				break; +	case FLASH_AM800T:	printf ("AM29LV800T (8 Mbit, top boot sector)\n"); +				break; +	case FLASH_AM160B:	printf ("AM29LV160B (16 Mbit, bottom boot sect)\n"); +				break; +	case FLASH_AM160T:	printf ("AM29LV160T (16 Mbit, top boot sector)\n"); +				break; +	case FLASH_AM320T:	printf ("AM29LV320T (32 M, top sector)\n"); +				break; +	case FLASH_AM320B:	printf ("AM29LV320B (32 M, bottom sector)\n"); +				break; +	case FLASH_AMDL322T:	printf ("AM29DL322T (32 M, top sector)\n"); +				break; +	case FLASH_AMDL322B:	printf ("AM29DL322B (32 M, bottom sector)\n"); +				break; +	case FLASH_AMDL323T:	printf ("AM29DL323T (32 M, top sector)\n"); +				break; +	case FLASH_AMDL323B:	printf ("AM29DL323B (32 M, bottom sector)\n"); +				break; +	case FLASH_AM640U:	printf ("AM29LV640D (64 M, uniform sector)\n"); +				break; +	case FLASH_SST800A:	printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n"); +				break; +	case FLASH_SST160A:	printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n"); +				break; +	case FLASH_SST320:	printf ("SST39LF/VF320 (32 Mbit, uniform sector size)\n"); +				break; +	case FLASH_SST640:	printf ("SST39LF/VF640 (64 Mbit, uniform sector size)\n"); +				break; +	default:		printf ("Unknown Chip Type\n"); +				break; +	} + +	printf ("  Size: %ld MB in %d Sectors\n", +		info->size >> 20, info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i=0; i<info->sector_count; ++i) { +#ifdef CONFIG_SYS_FLASH_EMPTY_INFO +		/* +		 * Check if whole sector is erased +		 */ +		if (i != (info->sector_count-1)) +		  size = info->start[i+1] - info->start[i]; +		else +		  size = info->start[0] + info->size - info->start[i]; +		erased = 1; +		flash = (volatile unsigned long *)info->start[i]; +		size = size >> 2;        /* divide by 4 for longword access */ +		for (k=0; k<size; k++) +		  { +		    if (*flash++ != 0xffffffff) +		      { +			erased = 0; +			break; +		      } +		  } + +		if ((i % 5) == 0) +			printf ("\n   "); +		/* print empty and read-only info */ +		printf (" %08lX%s%s", +			info->start[i], +			erased ? " E" : "  ", +			info->protect[i] ? "RO " : "   "); +#else +		if ((i % 5) == 0) +			printf ("\n   "); +		printf (" %08lX%s", +			info->start[i], +			info->protect[i] ? " (RO)" : "     "); +#endif + +	} +	printf ("\n"); +	return; +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ +	short i; +	short n; +	CONFIG_SYS_FLASH_WORD_SIZE value; +	ulong base = (ulong)addr; +	volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)addr; + +	/* Write auto select command: read Manufacturer ID */ +	addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; +	addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; +	addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00900090; + +	value = addr2[CONFIG_SYS_FLASH_READ0]; + +	switch (value) { +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_MANUFACT: +		info->flash_id = FLASH_MAN_AMD; +		break; +	case (CONFIG_SYS_FLASH_WORD_SIZE)FUJ_MANUFACT: +		info->flash_id = FLASH_MAN_FUJ; +		break; +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_MANUFACT: +		info->flash_id = FLASH_MAN_SST; +		break; +	case (CONFIG_SYS_FLASH_WORD_SIZE)EXCEL_MANUFACT: +		info->flash_id = FLASH_MAN_EXCEL; +		break; +	default: +		info->flash_id = FLASH_UNKNOWN; +		info->sector_count = 0; +		info->size = 0; +		return (0);			/* no or unknown flash	*/ +	} + +	value = addr2[CONFIG_SYS_FLASH_READ1];		/* device ID		*/ + +	switch (value) { +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400T: +		info->flash_id += FLASH_AM400T; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;				/* => 0.5 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV400B: +		info->flash_id += FLASH_AM400B; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;				/* => 0.5 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800T: +		info->flash_id += FLASH_AM800T; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;				/* => 1 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV800B: +		info->flash_id += FLASH_AM800B; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;				/* => 1 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160T: +		info->flash_id += FLASH_AM160T; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;				/* => 2 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV160B: +		info->flash_id += FLASH_AM160B; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;				/* => 2 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T: +		info->flash_id += FLASH_AM320T; +		info->sector_count = 71; +		info->size = 0x00400000;  break;	/* => 4 MB	*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B: +		info->flash_id += FLASH_AM320B; +		info->sector_count = 71; +		info->size = 0x00400000;  break;	/* => 4 MB	*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322T: +		info->flash_id += FLASH_AMDL322T; +		info->sector_count = 71; +		info->size = 0x00400000;  break;	/* => 4 MB	*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL322B: +		info->flash_id += FLASH_AMDL322B; +		info->sector_count = 71; +		info->size = 0x00400000;  break;	/* => 4 MB	*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323T: +		info->flash_id += FLASH_AMDL323T; +		info->sector_count = 71; +		info->size = 0x00400000;  break;	/* => 4 MB	*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_DL323B: +		info->flash_id += FLASH_AMDL323B; +		info->sector_count = 71; +		info->size = 0x00400000;  break;	/* => 4 MB	*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV640U: +		info->flash_id += FLASH_AM640U; +		info->sector_count = 128; +		info->size = 0x00800000;  break;	/* => 8 MB	*/ + +#if !(defined(CONFIG_ADCIOP) || defined(CONFIG_DASA_SIM)) +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF800A: +		info->flash_id += FLASH_SST800A; +		info->sector_count = 16; +		info->size = 0x00100000; +		break;				/* => 1 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF160A: +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF1601: +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF1602: +		info->flash_id += FLASH_SST160A; +		info->sector_count = 32; +		info->size = 0x00200000; +		break;				/* => 2 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF3201: +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF3202: +		info->flash_id += FLASH_SST320; +		info->sector_count = 64; +		info->size = 0x00400000; +		break;				/* => 4 MB		*/ + +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF6401: +	case (CONFIG_SYS_FLASH_WORD_SIZE)SST_ID_xF6402: +		info->flash_id += FLASH_SST640; +		info->sector_count = 128; +		info->size = 0x00800000; +		break;				/* => 8 MB		*/ +#endif + +	default: +		info->flash_id = FLASH_UNKNOWN; +		return (0);			/* => no or unknown flash */ + +	} + +	/* set up sector start address table */ +	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || +	    ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM640U)) { +	    for (i = 0; i < info->sector_count; i++) +		info->start[i] = base + (i * 0x00010000); +	} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322B) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323B) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324B)) { +		/* set sector offsets for bottom boot block type	*/ +		for (i=0; i<8; ++i) {		/*  8 x 8k boot sectors	*/ +			info->start[i] = base; +			base += 8 << 10; +		} +		while (i < info->sector_count) {	/* 64k regular sectors	*/ +			info->start[i] = base; +			base += 64 << 10; +			++i; +		} +	} else if (((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL322T) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL323T) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320T) || +		   ((info->flash_id & FLASH_TYPEMASK) == FLASH_AMDL324T)) { +		/* set sector offsets for top boot block type		*/ +		base += info->size; +		i = info->sector_count; +		for (n=0; n<8; ++n) {		/*  8 x 8k boot sectors	*/ +			base -= 8 << 10; +			--i; +			info->start[i] = base; +		} +		while (i > 0) {			/* 64k regular sectors	*/ +			base -= 64 << 10; +			--i; +			info->start[i] = base; +		} +	} else { +	    if (info->flash_id & FLASH_BTYPE) { +		/* set sector offsets for bottom boot block type	*/ +		info->start[0] = base + 0x00000000; +		info->start[1] = base + 0x00004000; +		info->start[2] = base + 0x00006000; +		info->start[3] = base + 0x00008000; +		for (i = 4; i < info->sector_count; i++) { +			info->start[i] = base + (i * 0x00010000) - 0x00030000; +		} +	    } else { +		/* set sector offsets for top boot block type		*/ +		i = info->sector_count - 1; +		info->start[i--] = base + info->size - 0x00004000; +		info->start[i--] = base + info->size - 0x00006000; +		info->start[i--] = base + info->size - 0x00008000; +		for (; i >= 0; i--) { +			info->start[i] = base + i * 0x00010000; +		} +	    } +	} + +	/* check for protected sectors */ +	for (i = 0; i < info->sector_count; i++) { +		/* read sector protection at sector address, (A7 .. A0) = 0x02 */ +		/* D0 = 1 if protected */ +		addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]); +		if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_AMD) +		  info->protect[i] = 0; +		else +		  info->protect[i] = addr2[CONFIG_SYS_FLASH_READ2] & 1; +	} + +	/* +	 * Prevent writes to uninitialized FLASH. +	 */ +	if (info->flash_id != FLASH_UNKNOWN) { +		addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0]; +		*addr2 = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0;	/* reset bank */ +	} + +	return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int	flash_erase (flash_info_t *info, int s_first, int s_last) +{ +	volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]); +	volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2; +	int flag, prot, sect, l_sect; +	ulong start, now, last; +	int i; + +	if ((s_first < 0) || (s_first > s_last)) { +		if (info->flash_id == FLASH_UNKNOWN) { +			printf ("- missing\n"); +		} else { +			printf ("- no sectors to erase\n"); +		} +		return 1; +	} + +	if (info->flash_id == FLASH_UNKNOWN) { +		printf ("Can't erase unknown flash type - aborted\n"); +		return 1; +	} + +	prot = 0; +	for (sect=s_first; sect<=s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		} +	} + +	if (prot) { +		printf ("- Warning: %d protected sectors will not be erased!\n", +			prot); +	} else { +		printf ("\n"); +	} + +	l_sect = -1; + +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts(); + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect<=s_last; sect++) { +		if (info->protect[sect] == 0) {	/* not protected */ +		    addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[sect]); +		    if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) { +			addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; +			addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; +			addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080; +			addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; +			addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; +			addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00500050;  /* block erase */ +			for (i=0; i<50; i++) +			  udelay(1000);  /* wait 1 ms */ +		    } else { +			if (sect == s_first) { +			    addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; +			    addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; +			    addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080; +			    addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; +			    addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; +			} +			addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00300030;  /* sector erase */ +		    } +		    l_sect = sect; +		} +	} + +	/* re-enable interrupts if necessary */ +	if (flag) +		enable_interrupts(); + +	/* wait at least 80us - let's wait 1 ms */ +	udelay (1000); + +	/* +	 * We wait for the last triggered sector +	 */ +	if (l_sect < 0) +		goto DONE; + +	start = get_timer (0); +	last  = start; +	addr = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[l_sect]); +	while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) { +		if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) { +			printf ("Timeout\n"); +			return 1; +		} +		/* show that we're waiting */ +		if ((now - last) > 1000) {	/* every second */ +			putc ('.'); +			last = now; +		} +	} + +DONE: +	/* reset to read mode */ +	addr = (CONFIG_SYS_FLASH_WORD_SIZE *)info->start[0]; +	addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00F000F0;	/* reset bank */ + +	printf (" done\n"); +	return 0; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ + +int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) +{ +	ulong cp, wp, data; +	int i, l, rc; + +	wp = (addr & ~3);	/* get lower word aligned address */ + +	/* +	 * handle unaligned start bytes +	 */ +	if ((l = addr - wp) != 0) { +		data = 0; +		for (i=0, cp=wp; i<l; ++i, ++cp) { +			data = (data << 8) | (*(uchar *)cp); +		} +		for (; i<4 && cnt>0; ++i) { +			data = (data << 8) | *src++; +			--cnt; +			++cp; +		} +		for (; cnt==0 && i<4; ++i, ++cp) { +			data = (data << 8) | (*(uchar *)cp); +		} + +		if ((rc = write_word(info, wp, data)) != 0) { +			return (rc); +		} +		wp += 4; +	} + +	/* +	 * handle word aligned part +	 */ +	while (cnt >= 4) { +		data = 0; +		for (i=0; i<4; ++i) { +			data = (data << 8) | *src++; +		} +		if ((rc = write_word(info, wp, data)) != 0) { +			return (rc); +		} +		wp  += 4; +		cnt -= 4; +	} + +	if (cnt == 0) { +		return (0); +	} + +	/* +	 * handle unaligned tail bytes +	 */ +	data = 0; +	for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { +		data = (data << 8) | *src++; +		--cnt; +	} +	for (; i<4; ++i, ++cp) { +		data = (data << 8) | (*(uchar *)cp); +	} + +	return (write_word(info, wp, data)); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_word (flash_info_t *info, ulong dest, ulong data) +{ +	ulong *data_ptr = &data; +	volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[0]); +	volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *)dest; +	volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *)data_ptr; +	ulong start; +	int flag; +	int i; + +	/* Check if Flash is (sufficiently) erased */ +	if ((*((vu_long *)dest) & data) != data) { +		return (2); +	} + +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts(); + +	for (i=0; i<4/sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) +	  { +	    addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00AA00AA; +	    addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00550055; +	    addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE)0x00A000A0; + +	    dest2[i] = data2[i]; + +	    /* re-enable interrupts if necessary */ +	    if (flag) +	      enable_interrupts(); + +	    /* data polling for D7 */ +	    start = get_timer (0); +	    while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080) != +		   (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE)0x00800080)) { +	      if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { +		return (1); +	      } +	    } +	  } + +	return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/roms/u-boot/board/esd/common/fpga.c b/roms/u-boot/board/esd/common/fpga.c new file mode 100644 index 00000000..5c70b474 --- /dev/null +++ b/roms/u-boot/board/esd/common/fpga.c @@ -0,0 +1,261 @@ +/* + * (C) Copyright 2001-2004 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <command.h> + +/* ------------------------------------------------------------------------- */ + +#ifdef FPGA_DEBUG +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +#define MAX_ONES               226 + +#ifdef CONFIG_SYS_FPGA_PRG +# define FPGA_PRG              CONFIG_SYS_FPGA_PRG	/* FPGA program pin (ppc output) */ +# define FPGA_CLK              CONFIG_SYS_FPGA_CLK	/* FPGA clk pin (ppc output)    */ +# define FPGA_DATA             CONFIG_SYS_FPGA_DATA	/* FPGA data pin (ppc output)  */ +# define FPGA_DONE             CONFIG_SYS_FPGA_DONE	/* FPGA done pin (ppc input)   */ +# define FPGA_INIT             CONFIG_SYS_FPGA_INIT	/* FPGA init pin (ppc input)   */ +#else +# define FPGA_PRG              0x04000000	/* FPGA program pin (ppc output) */ +# define FPGA_CLK              0x02000000	/* FPGA clk pin (ppc output)     */ +# define FPGA_DATA             0x01000000	/* FPGA data pin (ppc output)    */ +# define FPGA_DONE             0x00800000	/* FPGA done pin (ppc input)     */ +# define FPGA_INIT             0x00400000	/* FPGA init pin (ppc input)     */ +#endif + +#define ERROR_FPGA_PRG_INIT_LOW  -1	/* Timeout after PRG* asserted   */ +#define ERROR_FPGA_PRG_INIT_HIGH -2	/* Timeout after PRG* deasserted */ +#define ERROR_FPGA_PRG_DONE      -3	/* Timeout after programming     */ + +#ifndef SET_FPGA +# define SET_FPGA(data)         out_be32((void *)GPIO0_OR, data) +#endif + +#ifdef FPGA_PROG_ACTIVE_HIGH +# define FPGA_PRG_LOW           FPGA_PRG +# define FPGA_PRG_HIGH          0 +#else +# define FPGA_PRG_LOW           0 +# define FPGA_PRG_HIGH          FPGA_PRG +#endif + +#define FPGA_CLK_LOW            0 +#define FPGA_CLK_HIGH           FPGA_CLK + +#define FPGA_DATA_LOW           0 +#define FPGA_DATA_HIGH          FPGA_DATA + +#define FPGA_WRITE_1 {                                                                   \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set clock to 0 */  \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set data to 1  */  \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);  /* set clock to 1 */  \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);}	/* set data to 1  */ + +#define FPGA_WRITE_0 {                                                    \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_HIGH);  /* set clock to 0 */  \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_LOW  | FPGA_DATA_LOW);   /* set data to 0  */  \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_LOW);   /* set clock to 1 */  \ +	SET_FPGA(FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);}	/* set data to 1  */ + +#ifndef FPGA_DONE_STATE +# define FPGA_DONE_STATE (in_be32((void *)GPIO0_IR) & FPGA_DONE) +#endif +#ifndef FPGA_INIT_STATE +# define FPGA_INIT_STATE (in_be32((void *)GPIO0_IR) & FPGA_INIT) +#endif + + +static int fpga_boot (const unsigned char *fpgadata, int size) +{ +	int i, index, len; +	int count; +	unsigned char b; + +#ifdef CONFIG_SYS_FPGA_SPARTAN2 +	int j; +#else +	int bit; +#endif + +	/* display infos on fpgaimage */ +	index = 15; +	for (i = 0; i < 4; i++) { +		len = fpgadata[index]; +		DBG ("FPGA: %s\n", &(fpgadata[index + 1])); +		index += len + 3; +	} + +#ifdef CONFIG_SYS_FPGA_SPARTAN2 +	/* search for preamble 0xFFFFFFFF */ +	while (1) { +		if ((fpgadata[index] == 0xff) && (fpgadata[index + 1] == 0xff) +		    && (fpgadata[index + 2] == 0xff) +		    && (fpgadata[index + 3] == 0xff)) +			break;	/* preamble found */ +		else +			index++; +	} +#else +	/* search for preamble 0xFF2X */ +	for (index = 0; index < size - 1; index++) { +		if ((fpgadata[index] == 0xff) +		    && ((fpgadata[index + 1] & 0xf0) == 0x30)) +			break; +	} +	index += 2; +#endif + +	DBG ("FPGA: configdata starts at position 0x%x\n", index); +	DBG ("FPGA: length of fpga-data %d\n", size - index); + +	/* +	 * Setup port pins for fpga programming +	 */ +#ifndef CONFIG_M5249 +	out_be32 ((void *)GPIO0_ODR, 0x00000000); /* no open drain pins */ +	/* setup for output */ +	out_be32 ((void *)GPIO0_TCR, +		  in_be32 ((void *)GPIO0_TCR) | +		  FPGA_PRG | FPGA_CLK | FPGA_DATA); +#endif +	SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);	/* set pins to high */ + +	DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); +	DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + +	/* +	 * Init fpga by asserting and deasserting PROGRAM* +	 */ +	SET_FPGA (FPGA_PRG_LOW | FPGA_CLK_HIGH | FPGA_DATA_HIGH);	/* set prog active */ + +	/* Wait for FPGA init line low */ +	count = 0; +	while (FPGA_INIT_STATE) { +		udelay (1000);	/* wait 1ms */ +		/* Check for timeout - 100us max, so use 3ms */ +		if (count++ > 3) { +			DBG ("FPGA: Booting failed!\n"); +			return ERROR_FPGA_PRG_INIT_LOW; +		} +	} + +	DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); +	DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + +	/* deassert PROGRAM* */ +	SET_FPGA (FPGA_PRG_HIGH | FPGA_CLK_HIGH | FPGA_DATA_HIGH);	/* set prog inactive */ + +	/* Wait for FPGA end of init period .  */ +	count = 0; +	while (!(FPGA_INIT_STATE)) { +		udelay (1000);	/* wait 1ms */ +		/* Check for timeout */ +		if (count++ > 3) { +			DBG ("FPGA: Booting failed!\n"); +			return ERROR_FPGA_PRG_INIT_HIGH; +		} +	} + +	DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); +	DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + +	DBG ("write configuration data into fpga\n"); +	/* write configuration-data into fpga... */ + +#ifdef CONFIG_SYS_FPGA_SPARTAN2 +	/* +	 * Load uncompressed image into fpga +	 */ +	for (i = index; i < size; i++) { +		b = fpgadata[i]; +		for (j = 0; j < 8; j++) { +			if ((b & 0x80) == 0x80) { +				FPGA_WRITE_1; +			} else { +				FPGA_WRITE_0; +			} +			b <<= 1; +		} +	} +#else +	/* send 0xff 0x20 */ +	FPGA_WRITE_1; +	FPGA_WRITE_1; +	FPGA_WRITE_1; +	FPGA_WRITE_1; +	FPGA_WRITE_1; +	FPGA_WRITE_1; +	FPGA_WRITE_1; +	FPGA_WRITE_1; +	FPGA_WRITE_0; +	FPGA_WRITE_0; +	FPGA_WRITE_1; +	FPGA_WRITE_0; +	FPGA_WRITE_0; +	FPGA_WRITE_0; +	FPGA_WRITE_0; +	FPGA_WRITE_0; + +	/* +	 ** Bit_DeCompression +	 **   Code 1           .. maxOnes     : n                 '1's followed by '0' +	 **        maxOnes + 1 .. maxOnes + 1 : n - 1             '1's no '0' +	 **        maxOnes + 2 .. 254         : n - (maxOnes + 2) '0's followed by '1' +	 **        255                        :                   '1' +	 */ + +	for (i = index; i < size; i++) { +		b = fpgadata[i]; +		if ((b >= 1) && (b <= MAX_ONES)) { +			for (bit = 0; bit < b; bit++) { +				FPGA_WRITE_1; +			} +			FPGA_WRITE_0; +		} else if (b == (MAX_ONES + 1)) { +			for (bit = 1; bit < b; bit++) { +				FPGA_WRITE_1; +			} +		} else if ((b >= (MAX_ONES + 2)) && (b <= 254)) { +			for (bit = 0; bit < (b - (MAX_ONES + 2)); bit++) { +				FPGA_WRITE_0; +			} +			FPGA_WRITE_1; +		} else if (b == 255) { +			FPGA_WRITE_1; +		} +	} +#endif + +	DBG ("%s, ", (FPGA_DONE_STATE == 0) ? "NOT DONE" : "DONE"); +	DBG ("%s\n", (FPGA_INIT_STATE == 0) ? "NOT INIT" : "INIT"); + +	/* +	 * Check if fpga's DONE signal - correctly booted ? +	 */ + +	/* Wait for FPGA end of programming period .  */ +	count = 0; +	while (!(FPGA_DONE_STATE)) { +		udelay (1000);	/* wait 1ms */ +		/* Check for timeout */ +		if (count++ > 3) { +			DBG ("FPGA: Booting failed!\n"); +			return ERROR_FPGA_PRG_DONE; +		} +	} + +	DBG ("FPGA: Booting successful!\n"); +	return 0; +} diff --git a/roms/u-boot/board/esd/common/lcd.c b/roms/u-boot/board/esd/common/lcd.c new file mode 100644 index 00000000..22a59e44 --- /dev/null +++ b/roms/u-boot/board/esd/common/lcd.c @@ -0,0 +1,359 @@ +/* + * (C) Copyright 2003-2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * (C) Copyright 2005 + * Stefan Roese, DENX Software Engineering, sr@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include "asm/io.h" +#include "lcd.h" + + +extern int video_display_bitmap (ulong, int, int); + + +int palette_index; +int palette_value; +int lcd_depth; +unsigned char *glob_lcd_reg; +unsigned char *glob_lcd_mem; + +#if defined(CONFIG_SYS_LCD_ENDIAN) +void lcd_setup(int lcd, int config) +{ +	if (lcd == 0) { +		/* +		 * Set endianess and reset lcd controller 0 (small) +		 */ + +		/* set reset to low */ +		out_be32((void*)GPIO0_OR, +			 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD0_RST); +		udelay(10); /* wait 10us */ +		if (config == 1) { +			/* big-endian */ +			out_be32((void*)GPIO0_OR, +				 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN); +		} else { +			/* little-endian */ +			out_be32((void*)GPIO0_OR, +				 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD_ENDIAN); +		} +		udelay(10); /* wait 10us */ +		/* set reset to high */ +		out_be32((void*)GPIO0_OR, +			 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD0_RST); +	} else { +		/* +		 * Set endianess and reset lcd controller 1 (big) +		 */ + +		/* set reset to low */ +		out_be32((void*)GPIO0_OR, +			 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD1_RST); +		udelay(10); /* wait 10us */ +		if (config == 1) { +			/* big-endian */ +			out_be32((void*)GPIO0_OR, +				 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN); +		} else { +			/* little-endian */ +			out_be32((void*)GPIO0_OR, +				 in_be32((void*)GPIO0_OR) & ~CONFIG_SYS_LCD_ENDIAN); +		} +		udelay(10); /* wait 10us */ +		/* set reset to high */ +		out_be32((void*)GPIO0_OR, +			 in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD1_RST); +	} + +	/* +	 * CONFIG_SYS_LCD_ENDIAN may also be FPGA_RESET, so set inactive +	 */ +	out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | CONFIG_SYS_LCD_ENDIAN); +} +#endif /* CONFIG_SYS_LCD_ENDIAN */ + + +int lcd_bmp(uchar *logo_bmp) +{ +	int i; +	uchar *ptr; +	ushort *ptr2; +	ushort val; +	unsigned char *dst = NULL; +	int x, y; +	int width, height, bpp, colors, line_size; +	int header_size; +	unsigned char *bmp; +	unsigned char r, g, b; +	BITMAPINFOHEADER *bm_info; +	ulong len; + +	/* +	 * Check for bmp mark 'BM' +	 */ +	if (*(ushort *)logo_bmp != 0x424d) { +		/* +		 * Decompress bmp image +		 */ +		len = CONFIG_SYS_VIDEO_LOGO_MAX_SIZE; +		dst = malloc(CONFIG_SYS_VIDEO_LOGO_MAX_SIZE); +		if (dst == NULL) { +			printf("Error: malloc for gunzip failed!\n"); +			return 1; +		} +		if (gunzip(dst, CONFIG_SYS_VIDEO_LOGO_MAX_SIZE, +			   (uchar *)logo_bmp, &len) != 0) { +			free(dst); +			return 1; +		} +		if (len == CONFIG_SYS_VIDEO_LOGO_MAX_SIZE) { +			printf("Image could be truncated" +			       " (increase CONFIG_SYS_VIDEO_LOGO_MAX_SIZE)!\n"); +		} + +		/* +		 * Check for bmp mark 'BM' +		 */ +		if (*(ushort *)dst != 0x424d) { +			printf("LCD: Unknown image format!\n"); +			free(dst); +			return 1; +		} +	} else { +		/* +		 * Uncompressed BMP image, just use this pointer +		 */ +		dst = (uchar *)logo_bmp; +	} + +	/* +	 * Get image info from bmp-header +	 */ +	bm_info = (BITMAPINFOHEADER *)(dst + 14); +	bpp = LOAD_SHORT(bm_info->biBitCount); +	width = LOAD_LONG(bm_info->biWidth); +	height = LOAD_LONG(bm_info->biHeight); +	switch (bpp) { +	case 1: +		colors = 1; +		line_size = width >> 3; +		break; +	case 4: +		colors = 16; +		line_size = width >> 1; +		break; +	case 8: +		colors = 256; +		line_size = width; +		break; +	case 24: +		colors = 0; +		line_size = width * 3; +		break; +	default: +		printf("LCD: Unknown bpp (%d) im image!\n", bpp); +		if ((dst != NULL) && (dst != (uchar *)logo_bmp)) +			free(dst); +		return 1; +	} +	printf(" (%d*%d, %dbpp)\n", width, height, bpp); + +	/* +	 * Write color palette +	 */ +	if ((colors <= 256) && (lcd_depth <= 8)) { +		ptr = (unsigned char *)(dst + 14 + 40); +		for (i = 0; i < colors; i++) { +			b = *ptr++; +			g = *ptr++; +			r = *ptr++; +			ptr++; +			S1D_WRITE_PALETTE(glob_lcd_reg, i, r, g, b); +		} +	} + +	/* +	 * Write bitmap data into framebuffer +	 */ +	ptr = glob_lcd_mem; +	ptr2 = (ushort *)glob_lcd_mem; +	header_size = 14 + 40 + 4*colors;          /* skip bmp header */ +	for (y = 0; y < height; y++) { +		bmp = &dst[(height-1-y)*line_size + header_size]; +		if (lcd_depth == 16) { +			if (bpp == 24) { +				for (x = 0; x < width; x++) { +					/* +					 * Generate epson 16bpp fb-format +					 * from 24bpp image +					 */ +					b = *bmp++ >> 3; +					g = *bmp++ >> 2; +					r = *bmp++ >> 3; +					val = ((r & 0x1f) << 11) | +						((g & 0x3f) << 5) | +						(b & 0x1f); +					*ptr2++ = val; +				} +			} else if (bpp == 8) { +				for (x = 0; x < line_size; x++) { +					/* query rgb value from palette */ +					ptr = (unsigned char *)(dst + 14 + 40); +					ptr += (*bmp++) << 2; +					b = *ptr++ >> 3; +					g = *ptr++ >> 2; +					r = *ptr++ >> 3; +					val = ((r & 0x1f) << 11) | +						((g & 0x3f) << 5) | +						(b & 0x1f); +					*ptr2++ = val; +				} +			} +		} else { +			for (x = 0; x < line_size; x++) +				*ptr++ = *bmp++; +		} +	} + +	if ((dst != NULL) && (dst != (uchar *)logo_bmp)) +		free(dst); +	return 0; +} + + +int lcd_init(uchar *lcd_reg, uchar *lcd_mem, S1D_REGS *regs, int reg_count, +	     uchar *logo_bmp, ulong len) +{ +	int i; +	ushort s1dReg; +	uchar s1dValue; +	int reg_byte_swap; + +	/* +	 * Detect epson +	 */ +	out_8(&lcd_reg[0], 0x00); +	out_8(&lcd_reg[1], 0x00); + +	if (in_8(&lcd_reg[0]) == 0x1c) { +		/* +		 * Big epson detected +		 */ +		reg_byte_swap = false; +		palette_index = 0x1e2; +		palette_value = 0x1e4; +		lcd_depth = 16; +		puts("LCD:   S1D13806"); +	} else if (in_8(&lcd_reg[1]) == 0x1c) { +		/* +		 * Big epson detected (with register swap bug) +		 */ +		reg_byte_swap = true; +		palette_index = 0x1e3; +		palette_value = 0x1e5; +		lcd_depth = 16; +		puts("LCD:   S1D13806S"); +	} else if (in_8(&lcd_reg[0]) == 0x18) { +		/* +		 * Small epson detected (704) +		 */ +		reg_byte_swap = false; +		palette_index = 0x15; +		palette_value = 0x17; +		lcd_depth = 8; +		puts("LCD:   S1D13704"); +	} else if (in_8(&lcd_reg[0x10000]) == 0x24) { +		/* +		 * Small epson detected (705) +		 */ +		reg_byte_swap = false; +		palette_index = 0x15; +		palette_value = 0x17; +		lcd_depth = 8; +		lcd_reg += 0x10000; /* add offset for 705 regs */ +		puts("LCD:   S1D13705"); +	} else { +		out_8(&lcd_reg[0x1a], 0x00); +		udelay(1000); +		if (in_8(&lcd_reg[1]) == 0x0c) { +			/* +			 * S1D13505 detected +			 */ +			reg_byte_swap = true; +			palette_index = 0x25; +			palette_value = 0x27; +			lcd_depth = 16; + +			puts("LCD:   S1D13505"); +		} else { +			puts("LCD:   No controller detected!\n"); +			return 1; +		} +	} + +	/* +	 * Setup lcd controller regs +	 */ +	for (i = 0; i < reg_count; i++) { +		s1dReg = regs[i].Index; +		if (reg_byte_swap) { +			if ((s1dReg & 0x0001) == 0) +				s1dReg |= 0x0001; +			else +				s1dReg &= ~0x0001; +		} +		s1dValue = regs[i].Value; +		out_8(&lcd_reg[s1dReg], s1dValue); +	} + +	/* +	 * Save reg & mem pointer for later usage (e.g. bmp command) +	 */ +	glob_lcd_reg = lcd_reg; +	glob_lcd_mem = lcd_mem; + +	/* +	 * Display bmp image +	 */ +	return lcd_bmp(logo_bmp); +} + +int do_esdbmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	ulong addr; +#ifdef CONFIG_VIDEO_SM501 +	char *str; +#endif +	if (argc != 2) +		return cmd_usage(cmdtp); + +	addr = simple_strtoul(argv[1], NULL, 16); + +#ifdef CONFIG_VIDEO_SM501 +	str = getenv("bd_type"); +	if ((strcmp(str, "ppc221") == 0) || (strcmp(str, "ppc231") == 0)) { +		/* +		 * SM501 available, use standard bmp command +		 */ +		return video_display_bitmap(addr, 0, 0); +	} else { +		/* +		 * No SM501 available, use esd epson bmp command +		 */ +		return lcd_bmp((uchar *)addr); +	} +#else +	return lcd_bmp((uchar *)addr); +#endif +} + +U_BOOT_CMD( +	esdbmp,	2,	1,	do_esdbmp, +	"display BMP image", +	"<imageAddr> - display image" +); diff --git a/roms/u-boot/board/esd/common/lcd.h b/roms/u-boot/board/esd/common/lcd.h new file mode 100644 index 00000000..5b14bf92 --- /dev/null +++ b/roms/u-boot/board/esd/common/lcd.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2003-2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * Neutralize little endians. + */ +#define SWAP_LONG(data) ((unsigned long)                                  \ +			 (((unsigned long)(data) >> 24)                 | \ +			  ((unsigned long)(data)  << 24)                | \ +			  (((unsigned long)(data) >> 8) & 0x0000ff00 )  | \ +			   (((unsigned long)(data) << 8) & 0x00ff0000 ))) +#define SWAP_SHORT(data) ((unsigned short)                                \ +			  (((unsigned short)(data) >> 8 )  |              \ +			   ((unsigned short)(data) << 8 ))) +#define LOAD_LONG(data)   SWAP_LONG(data) +#define LOAD_SHORT(data)  SWAP_SHORT(data) + +#define S1D_WRITE_PALETTE(p,i,r,g,b)					\ +	{								\ +		out_8(&((uchar*)(p))[palette_index], (uchar)(i));	\ +		out_8(&((uchar*)(p))[palette_index], (uchar)(r));	\ +		out_8(&((uchar*)(p))[palette_index], (uchar)(g));	\ +		out_8(&((uchar*)(p))[palette_index], (uchar)(b));	\ +	} + +typedef struct +{ +    ushort Index; +    uchar  Value; +} S1D_REGS; + +typedef struct                       /**** BMP file info structure ****/ +{ +	unsigned int   biSize;           /* Size of info header */ +	int            biWidth;          /* Width of image */ +	int            biHeight;         /* Height of image */ +	unsigned short biPlanes;         /* Number of color planes */ +	unsigned short biBitCount;       /* Number of bits per pixel */ +	unsigned int   biCompression;    /* Type of compression to use */ +	unsigned int   biSizeImage;      /* Size of image data */ +	int            biXPelsPerMeter;  /* X pixels per meter */ +	int            biYPelsPerMeter;  /* Y pixels per meter */ +	unsigned int   biClrUsed;        /* Number of colors used */ +	unsigned int   biClrImportant;   /* Number of important colors */ +} BITMAPINFOHEADER; diff --git a/roms/u-boot/board/esd/common/misc.c b/roms/u-boot/board/esd/common/misc.c new file mode 100644 index 00000000..79cd6127 --- /dev/null +++ b/roms/u-boot/board/esd/common/misc.c @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2004 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +#ifdef CONFIG_LXT971_NO_SLEEP +#include <miiphy.h> +#endif + + +#ifdef CONFIG_LXT971_NO_SLEEP +void lxt971_no_sleep(void) +{ +	unsigned short reg; + +	miiphy_read("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, ®); +	reg &= ~0x0040;                  /* disable sleep mode */ +	miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, reg); +} +#endif /* CONFIG_LXT971_NO_SLEEP */ diff --git a/roms/u-boot/board/esd/common/pci.c b/roms/u-boot/board/esd/common/pci.c new file mode 100644 index 00000000..faebdb18 --- /dev/null +++ b/roms/u-boot/board/esd/common/pci.c @@ -0,0 +1,186 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/ppc4xx.h> +#include <asm/processor.h> +#include <pci.h> + + +u_long pci9054_iobase; + + +#define PCI_PRIMARY_CAR	(0x500000dc) /* PCI config address reg */ +#define PCI_PRIMARY_CDR	(0x80000000) /* PCI config data    reg */ + + +/*-----------------------------------------------------------------------------+ +|  Subroutine:  pci9054_read_config_dword +|  Description: Read a PCI configuration register +|  Inputs: +|               hose            PCI Controller +|               dev             PCI Bus+Device+Function number +|               offset          Configuration register number +|               value           Address of the configuration register value +|  Return value: +|               0               Successful ++-----------------------------------------------------------------------------*/ +int pci9054_read_config_dword(struct pci_controller *hose, +			      pci_dev_t dev, int offset, u32* value) +{ +  unsigned long      conAdrVal; +  unsigned long      val; + +  /* generate coded value for CON_ADR register */ +  conAdrVal = dev | (offset & 0xfc) | 0x80000000; + +  /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */ +  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal; + +  /* Note: *pResult comes back as -1 if machine check happened */ +  val = in32r(PCI_PRIMARY_CDR); + +  *value = (unsigned long) val; + +  out32r(PCI_PRIMARY_CAR, 0); + +  if ((*(unsigned long *)0x50000304) & 0x60000000) +    { +      /* clear pci master/target abort bits */ +      *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304; +    } + +  return 0; +} + +/*-----------------------------------------------------------------------------+ +|  Subroutine:  pci9054_write_config_dword +|  Description: Write a PCI configuration register. +|  Inputs: +|               hose            PCI Controller +|               dev             PCI Bus+Device+Function number +|               offset          Configuration register number +|               Value           Configuration register value +|  Return value: +|               0               Successful +| Updated for pass2 errata #6. Need to disable interrupts and clear the +| PCICFGADR reg after writing the PCICFGDATA reg. ++-----------------------------------------------------------------------------*/ +int pci9054_write_config_dword(struct pci_controller *hose, +			       pci_dev_t dev, int offset, u32 value) +{ +  unsigned long      conAdrVal; + +  conAdrVal = dev | (offset & 0xfc) | 0x80000000; + +  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal; + +  out32r(PCI_PRIMARY_CDR, value); + +  out32r(PCI_PRIMARY_CAR, 0); + +  /* clear pci master/target abort bits */ +  *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304; + +  return (0); +} + +/*----------------------------------------------------------------------- + */ + +#ifdef CONFIG_DASA_SIM +static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev, +					struct pci_config_table *_) +{ +  unsigned int iobase; +  unsigned short status = 0; +  unsigned char timer; + +  /* +   * Configure PLX PCI9054 +   */ +  pci_read_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, &status); +  status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; +  pci_write_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, status); + +  /* Check the latency timer for values >= 0x60. +   */ +  pci_read_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer); +  if (timer < 0x60) +    { +      pci_write_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60); +    } + +  /* Set I/O base register. +   */ +  pci_write_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CONFIG_SYS_PCI9054_IOBASE); +  pci_read_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase); + +  pci9054_iobase = pci_mem_to_phys(CONFIG_SYS_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK); + +  if (pci9054_iobase == 0xffffffff) +    { +      printf("Error: Can not set I/O base register.\n"); +      return; +    } +} +#endif + +static struct pci_config_table pci9054_config_table[] = { +#ifndef CONFIG_PCI_PNP +  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, +    PCI_BUS(CONFIG_SYS_ETH_DEV_FN), PCI_DEV(CONFIG_SYS_ETH_DEV_FN), PCI_FUNC(CONFIG_SYS_ETH_DEV_FN), +    pci_cfgfunc_config_device, { CONFIG_SYS_ETH_IOBASE, +				 CONFIG_SYS_ETH_IOBASE, +				 PCI_COMMAND_IO | PCI_COMMAND_MASTER }}, +#ifdef CONFIG_DASA_SIM +  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, +    PCI_BUS(CONFIG_SYS_PCI9054_DEV_FN), PCI_DEV(CONFIG_SYS_PCI9054_DEV_FN), PCI_FUNC(CONFIG_SYS_PCI9054_DEV_FN), +    pci_dasa_sim_config_pci9054 }, +#endif +#endif +  { } +}; + +static struct pci_controller pci9054_hose = { +  config_table: pci9054_config_table, +}; + +void pci_init_board(void) +{ +  struct pci_controller *hose = &pci9054_hose; + +  /* +   * Register the hose +   */ +  hose->first_busno = 0; +  hose->last_busno = 0xff; + +  /* System memory space */ +  pci_set_region(hose->regions + 0, +		 0x00000000, 0x00000000, 0x01000000, +		 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + +  /* PCI Memory space */ +  pci_set_region(hose->regions + 1, +		 0x00000000, 0xc0000000, 0x10000000, +		 PCI_REGION_MEM); + +  pci_set_ops(hose, +	      pci_hose_read_config_byte_via_dword, +	      pci_hose_read_config_word_via_dword, +	      pci9054_read_config_dword, +	      pci_hose_write_config_byte_via_dword, +	      pci_hose_write_config_word_via_dword, +	      pci9054_write_config_dword); + +  hose->region_count = 2; + +  pci_register_hose(hose); + +  hose->last_busno = pci_hose_scan(hose); +} diff --git a/roms/u-boot/board/esd/common/s1d13505_640_480_16bpp.h b/roms/u-boot/board/esd/common/s1d13505_640_480_16bpp.h new file mode 100644 index 00000000..ca11683a --- /dev/null +++ b/roms/u-boot/board/esd/common/s1d13505_640_480_16bpp.h @@ -0,0 +1,49 @@ +/* + * (C) Copyright 2008 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* + * Panel:  640x480 50Hz TFT Single 18-bit (PCLK=20.000 MHz) + * Memory:  DRAM (MCLK=40.000 MHz) + */ +static S1D_REGS regs_13505_640_480_16bpp[] = +{ +	{0x1B,0x00},   /* Miscellaneous Register */ +	{0x23,0x20},   /* Performance Enhancement Register 1 */ +	{0x01,0x30},   /* Memory Configuration Register */ +	{0x22,0x24},   /* Performance Enhancement Register 0 */ +	{0x02,0x25},   /* Panel Type Register */ +	{0x03,0x00},   /* MOD Rate Register */ +	{0x04,0x4F},   /* Horizontal Display Width Register */ +	{0x05,0x0c},   /* Horizontal Non-Display Period Register */ +	{0x06,0x00},   /* HRTC/FPLINE Start Position Register */ +	{0x07,0x01},   /* HRTC/FPLINE Pulse Width Register */ +	{0x08,0xDF},   /* Vertical Display Height Register 0 */ +	{0x09,0x01},   /* Vertical Display Height Register 1 */ +	{0x0A,0x3E},   /* Vertical Non-Display Period Register */ +	{0x0B,0x00},   /* VRTC/FPFRAME Start Position Register */ +	{0x0C,0x01},   /* VRTC/FPFRAME Pulse Width Register */ +	{0x0E,0xFF},   /* Screen 1 Line Compare Register 0 */ +	{0x0F,0x03},   /* Screen 1 Line Compare Register 1 */ +	{0x10,0x00},   /* Screen 1 Display Start Address Register 0 */ +	{0x11,0x00},   /* Screen 1 Display Start Address Register 1 */ +	{0x12,0x00},   /* Screen 1 Display Start Address Register 2 */ +	{0x13,0x00},   /* Screen 2 Display Start Address Register 0 */ +	{0x14,0x00},   /* Screen 2 Display Start Address Register 1 */ +	{0x15,0x00},   /* Screen 2 Display Start Address Register 2 */ +	{0x16,0x80},   /* Memory Address Offset Register 0 */ +	{0x17,0x02},   /* Memory Address Offset Register 1 */ +	{0x18,0x00},   /* Pixel Panning Register */ +	{0x19,0x01},   /* Clock Configuration Register */ +	{0x1A,0x00},   /* Power Save Configuration Register */ +	{0x1C,0x00},   /* MD Configuration Readback Register 0 */ +	{0x1E,0x06},   /* General IO Pins Configuration Register 0 */ +	{0x1F,0x00},   /* General IO Pins Configuration Register 1 */ +	{0x20,0x00},   /* General IO Pins Control Register 0 */ +	{0x21,0x00},   /* General IO Pins Control Register 1 */ +	{0x23,0x20},   /* Performance Enhancement Register 1 */ +	{0x0D,0x15},   /* Display Mode Register */ +}; diff --git a/roms/u-boot/board/esd/common/s1d13704_320_240_4bpp.h b/roms/u-boot/board/esd/common/s1d13704_320_240_4bpp.h new file mode 100644 index 00000000..bd910e8b --- /dev/null +++ b/roms/u-boot/board/esd/common/s1d13704_320_240_4bpp.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + * + * Generic Header information generated by 13704CFG.EXE (Build 10) + * Panel: 320x240x4bpp 78Hz Mono 4-Bit STN, Disabled (PCLK=6.666MHz) + */ + +static S1D_REGS regs_13704_320_240_4bpp[] = +{ +	{ 0x00,             0x00 },       /* Revision Code Register */ +	{ 0x01,             0x04 }, /*00*/      /* Mode Register 0 Register */ +	{ 0x02,             0xA4 }, /*a0*/      /* Mode Register 1 Register */ +	{ 0x03,             0x83 }, /*03*/      /* Mode Register 2 Register - bit7 is LUT bypass */ +	{ 0x04,             0x27 },       /* Horizontal Panel Size Register */ +	{ 0x05,             0xEF },       /* Vertical Panel Size Register (LSB) */ +	{ 0x06,             0x00 },       /* Vertical Panel Size Register (MSB) */ +	{ 0x07,             0x00 },       /* FPLINE Start Position Register */ +	{ 0x08,             0x00 },       /* Horizontal Non-Display Period Register */ +	{ 0x09,             0x00 },       /* FPFRAME Start Position Register */ +	{ 0x0A,             0x02 },       /* Vertical Non-Display Period Register */ +	{ 0x0B,             0x00 },       /* MOD Rate Register */ +	{ 0x0C,             0x00 },       /* Screen 1 Start Address Register (LSB) */ +	{ 0x0D,             0x00 },       /* Screen 1 Start Address Register (MSB) */ +	{ 0x0E,             0x00 },       /* Not Used */ +	{ 0x0F,             0x00 },       /* Screen 2 Start Address Register (LSB) */ +	{ 0x10,             0x00 },       /* Screen 2 Start Address Register (MSB) */ +	{ 0x11,             0x00 },       /* Not Used */ +	{ 0x12,             0x00 },       /* Memory Address Offset Register */ +	{ 0x13,             0xFF },       /* Screen 1 Vertical Size Register (LSB) */ +	{ 0x14,             0x03 },       /* Screen 1 Vertical Size Register (MSB) */ +	{ 0x15,             0x00 },       /* Look-Up Table Address Register */ +	{ 0x16,             0x00 },       /* Look-Up Table Bank Select Register */ +	{ 0x17,             0x00 },       /* Look-Up Table Data Register */ +	{ 0x18,             0x01 },       /* GPIO Configuration Control Register */ +	{ 0x19,             0x01 },       /* GPIO Status/Control Register */ +	{ 0x1A,             0x00 },       /* Scratch Pad Register */ +	{ 0x1B,             0x00 },       /* SwivelView Mode Register */ +	{ 0x1C,             0xA0 },       /* Line Byte Count Register */ +	{ 0x1D,             0x00 },       /* Not Used */ +	{ 0x1E,             0x00 },       /* Not Used */ +	{ 0x1F,             0x00 },       /* Not Used */ +}; diff --git a/roms/u-boot/board/esd/common/s1d13705_320_240_8bpp.h b/roms/u-boot/board/esd/common/s1d13705_320_240_8bpp.h new file mode 100644 index 00000000..041b4a93 --- /dev/null +++ b/roms/u-boot/board/esd/common/s1d13705_320_240_8bpp.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + * + * Generic Header information generated by 13704CFG.EXE (Build 10) + * Panel: 320x240x8bpp 78Hz Mono 8-Bit STN, Disabled (PCLK=6.666MHz) + */ + +static S1D_REGS regs_13705_320_240_8bpp[] = +{ +	{ 0x00,             0x00 },       /* Revision Code Register */ +	{ 0x01,             0x23 },       /* Mode Register 0 Register */ +	{ 0x02,             0xE0 },       /* Mode Register 1 Register */ +	{ 0x03,             0x03 },       /* Mode Register 2 Register - bit7 is LUT bypass */ +	{ 0x04,             0x27 },       /* Horizontal Panel Size Register */ +	{ 0x05,             0xEF },       /* Vertical Panel Size Register (LSB) */ +	{ 0x06,             0x00 },       /* Vertical Panel Size Register (MSB) */ +	{ 0x07,             0x00 },       /* FPLINE Start Position Register */ +	{ 0x08,             0x00 },       /* Horizontal Non-Display Period Register */ +	{ 0x09,             0x01 },       /* FPFRAME Start Position Register */ +	{ 0x0A,             0x02 },       /* Vertical Non-Display Period Register */ +	{ 0x0B,             0x00 },       /* MOD Rate Register */ +	{ 0x0C,             0x00 },       /* Screen 1 Start Address Register (LSB) */ +	{ 0x0D,             0x00 },       /* Screen 1 Start Address Register (MSB) */ +	{ 0x0E,             0x00 },       /* Not Used */ +	{ 0x0F,             0x00 },       /* Screen 2 Start Address Register (LSB) */ +	{ 0x10,             0x00 },       /* Screen 2 Start Address Register (MSB) */ +	{ 0x11,             0x00 },       /* Not Used */ +	{ 0x12,             0x00 },       /* Memory Address Offset Register */ +	{ 0x13,             0xFF },       /* Screen 1 Vertical Size Register (LSB) */ +	{ 0x14,             0x03 },       /* Screen 1 Vertical Size Register (MSB) */ +	{ 0x15,             0x00 },       /* Look-Up Table Address Register */ +	{ 0x16,             0x00 },       /* Look-Up Table Bank Select Register */ +	{ 0x17,             0x00 },       /* Look-Up Table Data Register */ +	{ 0x18,             0x01 },       /* GPIO Configuration Control Register */ +	{ 0x19,             0x01 },       /* GPIO Status/Control Register */ +	{ 0x1A,             0x00 },       /* Scratch Pad Register */ +	{ 0x1B,             0x00 },       /* SwivelView Mode Register */ +	{ 0x1C,             0xFF },       /* Line Byte Count Register */ +	{ 0x1D,             0x00 },       /* Not Used */ +	{ 0x1E,             0x00 },       /* Not Used */ +	{ 0x1F,             0x00 },       /* Not Used */ +}; diff --git a/roms/u-boot/board/esd/common/s1d13806_1024_768_8bpp.h b/roms/u-boot/board/esd/common/s1d13806_1024_768_8bpp.h new file mode 100644 index 00000000..615fa33a --- /dev/null +++ b/roms/u-boot/board/esd/common/s1d13806_1024_768_8bpp.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + * + * File generated by S1D13806CFG.EXE + * Panel:  (active)   1024x768 34Hz TFT Single 12-bit (PCLK=BUSCLK=33.333MHz) + * Memory: Embedded SDRAM (MCLK=CLKI=49.100MHz) (BUSCLK=33.333MHz) + */ + +static S1D_REGS regs_13806_1024_768_8bpp[] = +{ +	{0x0001,0x00},   /* Miscellaneous Register */ +	{0x01FC,0x00},   /* Display Mode Register */ +	{0x0004,0x00},   /* General IO Pins Configuration Register 0 */ +	{0x0005,0x00},   /* General IO Pins Configuration Register 1 */ +	{0x0008,0x00},   /* General IO Pins Control Register 0 */ +	{0x0009,0x00},   /* General IO Pins Control Register 1 */ +	{0x0010,0x00},   /* Memory Clock Configuration Register */ +	{0x0014,0x01},   /* LCD Pixel Clock Configuration Register */ +	{0x0018,0x00},   /* CRT/TV Pixel Clock Configuration Register */ +	{0x001C,0x02},   /* MediaPlug Clock Configuration Register */ +	{0x001E,0x01},   /* CPU To Memory Wait State Select Register */ +	{0x0021,0x03},   /* DRAM Refresh Rate Register */ +	{0x002A,0x00},   /* DRAM Timings Control Register 0 */ +	{0x002B,0x01},   /* DRAM Timings Control Register 1 */ +	{0x0020,0x80},   /* Memory Configuration Register */ +	{0x0030,0x55},   /* Panel Type Register */ +	{0x0031,0x00},   /* MOD Rate Register */ +	{0x0032,0x7F},   /* LCD Horizontal Display Width Register */ +	{0x0034,0x12},   /* LCD Horizontal Non-Display Period Register */ +	{0x0035,0x01},   /* TFT FPLINE Start Position Register */ +	{0x0036,0x0B},   /* TFT FPLINE Pulse Width Register */ +	{0x0038,0xFF},   /* LCD Vertical Display Height Register 0 */ +	{0x0039,0x02},   /* LCD Vertical Display Height Register 1 */ +	{0x003A,0x2C},   /* LCD Vertical Non-Display Period Register */ +	{0x003B,0x0A},   /* TFT FPFRAME Start Position Register */ +	{0x003C,0x01},   /* TFT FPFRAME Pulse Width Register */ +	{0x0040,0x03},   /* LCD Display Mode Register */ +	{0x0041,0x00},   /* LCD Miscellaneous Register */ +	{0x0042,0x00},   /* LCD Display Start Address Register 0 */ +	{0x0043,0x00},   /* LCD Display Start Address Register 1 */ +	{0x0044,0x00},   /* LCD Display Start Address Register 2 */ +	{0x0046,0x00},   /* LCD Memory Address Offset Register 0 */ +	{0x0047,0x02},   /* LCD Memory Address Offset Register 1 */ +	{0x0048,0x00},   /* LCD Pixel Panning Register */ +	{0x004A,0x00},   /* LCD Display FIFO High Threshold Control Register */ +	{0x004B,0x00},   /* LCD Display FIFO Low Threshold Control Register */ +	{0x0050,0x4F},   /* CRT/TV Horizontal Display Width Register */ +	{0x0052,0x13},   /* CRT/TV Horizontal Non-Display Period Register */ +	{0x0053,0x01},   /* CRT/TV HRTC Start Position Register */ +	{0x0054,0x0B},   /* CRT/TV HRTC Pulse Width Register */ +	{0x0056,0xDF},   /* CRT/TV Vertical Display Height Register 0 */ +	{0x0057,0x01},   /* CRT/TV Vertical Display Height Register 1 */ +	{0x0058,0x2B},   /* CRT/TV Vertical Non-Display Period Register */ +	{0x0059,0x09},   /* CRT/TV VRTC Start Position Register */ +	{0x005A,0x01},   /* CRT/TV VRTC Pulse Width Register */ +	{0x005B,0x10},   /* TV Output Control Register */ +	{0x0060,0x03},   /* CRT/TV Display Mode Register */ +	{0x0062,0x00},   /* CRT/TV Display Start Address Register 0 */ +	{0x0063,0x00},   /* CRT/TV Display Start Address Register 1 */ +	{0x0064,0x00},   /* CRT/TV Display Start Address Register 2 */ +	{0x0066,0x40},   /* CRT/TV Memory Address Offset Register 0 */ +	{0x0067,0x01},   /* CRT/TV Memory Address Offset Register 1 */ +	{0x0068,0x00},   /* CRT/TV Pixel Panning Register */ +	{0x006A,0x00},   /* CRT/TV Display FIFO High Threshold Control Register */ +	{0x006B,0x00},   /* CRT/TV Display FIFO Low Threshold Control Register */ +	{0x0070,0x00},   /* LCD Ink/Cursor Control Register */ +	{0x0071,0x01},   /* LCD Ink/Cursor Start Address Register */ +	{0x0072,0x00},   /* LCD Cursor X Position Register 0 */ +	{0x0073,0x00},   /* LCD Cursor X Position Register 1 */ +	{0x0074,0x00},   /* LCD Cursor Y Position Register 0 */ +	{0x0075,0x00},   /* LCD Cursor Y Position Register 1 */ +	{0x0076,0x00},   /* LCD Ink/Cursor Blue Color 0 Register */ +	{0x0077,0x00},   /* LCD Ink/Cursor Green Color 0 Register */ +	{0x0078,0x00},   /* LCD Ink/Cursor Red Color 0 Register */ +	{0x007A,0x1F},   /* LCD Ink/Cursor Blue Color 1 Register */ +	{0x007B,0x3F},   /* LCD Ink/Cursor Green Color 1 Register */ +	{0x007C,0x1F},   /* LCD Ink/Cursor Red Color 1 Register */ +	{0x007E,0x00},   /* LCD Ink/Cursor FIFO Threshold Register */ +	{0x0080,0x00},   /* CRT/TV Ink/Cursor Control Register */ +	{0x0081,0x01},   /* CRT/TV Ink/Cursor Start Address Register */ +	{0x0082,0x00},   /* CRT/TV Cursor X Position Register 0 */ +	{0x0083,0x00},   /* CRT/TV Cursor X Position Register 1 */ +	{0x0084,0x00},   /* CRT/TV Cursor Y Position Register 0 */ +	{0x0085,0x00},   /* CRT/TV Cursor Y Position Register 1 */ +	{0x0086,0x00},   /* CRT/TV Ink/Cursor Blue Color 0 Register */ +	{0x0087,0x00},   /* CRT/TV Ink/Cursor Green Color 0 Register */ +	{0x0088,0x00},   /* CRT/TV Ink/Cursor Red Color 0 Register */ +	{0x008A,0x1F},   /* CRT/TV Ink/Cursor Blue Color 1 Register */ +	{0x008B,0x3F},   /* CRT/TV Ink/Cursor Green Color 1 Register */ +	{0x008C,0x1F},   /* CRT/TV Ink/Cursor Red Color 1 Register */ +	{0x008E,0x00},   /* CRT/TV Ink/Cursor FIFO Threshold Register */ +	{0x0100,0x00},   /* BitBlt Control Register 0 */ +	{0x0101,0x00},   /* BitBlt Control Register 1 */ +	{0x0102,0x00},   /* BitBlt ROP Code/Color Expansion Register */ +	{0x0103,0x00},   /* BitBlt Operation Register */ +	{0x0104,0x00},   /* BitBlt Source Start Address Register 0 */ +	{0x0105,0x00},   /* BitBlt Source Start Address Register 1 */ +	{0x0106,0x00},   /* BitBlt Source Start Address Register 2 */ +	{0x0108,0x00},   /* BitBlt Destination Start Address Register 0 */ +	{0x0109,0x00},   /* BitBlt Destination Start Address Register 1 */ +	{0x010A,0x00},   /* BitBlt Destination Start Address Register 2 */ +	{0x010C,0x00},   /* BitBlt Memory Address Offset Register 0 */ +	{0x010D,0x00},   /* BitBlt Memory Address Offset Register 1 */ +	{0x0110,0x00},   /* BitBlt Width Register 0 */ +	{0x0111,0x00},   /* BitBlt Width Register 1 */ +	{0x0112,0x00},   /* BitBlt Height Register 0 */ +	{0x0113,0x00},   /* BitBlt Height Register 1 */ +	{0x0114,0x00},   /* BitBlt Background Color Register 0 */ +	{0x0115,0x00},   /* BitBlt Background Color Register 1 */ +	{0x0118,0x00},   /* BitBlt Foreground Color Register 0 */ +	{0x0119,0x00},   /* BitBlt Foreground Color Register 1 */ +	{0x01E0,0x00},   /* Look-Up Table Mode Register */ +	{0x01E2,0x00},   /* Look-Up Table Address Register */ +	{0x01F0,0x10},   /* Power Save Configuration Register */ +	{0x01F1,0x00},   /* Power Save Status Register */ +	{0x01F4,0x00},   /* CPU-to-Memory Access Watchdog Timer Register */ +	{0x01FC,0x01},   /* Display Mode Register */ +}; diff --git a/roms/u-boot/board/esd/common/s1d13806_320_240_4bpp.h b/roms/u-boot/board/esd/common/s1d13806_320_240_4bpp.h new file mode 100644 index 00000000..2531f474 --- /dev/null +++ b/roms/u-boot/board/esd/common/s1d13806_320_240_4bpp.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + * + * File generated by S1D13806CFG.EXE + * Panel:  (active)   320x240 62Hz STN Single 4-bit (PCLK=CLKI2/4=6.250MHz) + * Memory: Embedded SDRAM (MCLK=CLKI=49.500MHz) (BUSCLK=33.333MHz) + */ + +static S1D_REGS regs_13806_320_240_4bpp[] = +{ +	{0x0001,0x00},   /* Miscellaneous Register */ +	{0x01FC,0x00},   /* Display Mode Register */ +	{0x0004,0x08},   /* General IO Pins Configuration Register 0 */ +	{0x0005,0x08},   /* General IO Pins Configuration Register 1 */ +	{0x0008,0x08},   /* General IO Pins Control Register 0 */ +	{0x0009,0x00},   /* General IO Pins Control Register 1 */ +	{0x0010,0x00},   /* Memory Clock Configuration Register */ +	{0x0014,0x32},   /* LCD Pixel Clock Configuration Register */ +	{0x0018,0x00},   /* CRT/TV Pixel Clock Configuration Register */ +	{0x001C,0x02},   /* MediaPlug Clock Configuration Register */ +	{0x001E,0x01},   /* CPU To Memory Wait State Select Register */ +	{0x0021,0x03},   /* DRAM Refresh Rate Register */ +	{0x002A,0x00},   /* DRAM Timings Control Register 0 */ +	{0x002B,0x01},   /* DRAM Timings Control Register 1 */ +	{0x0020,0x80},   /* Memory Configuration Register */ +	{0x0030,0x00},   /* Panel Type Register */ +	{0x0031,0x00},   /* MOD Rate Register */ +	{0x0032,0x27},   /* LCD Horizontal Display Width Register */ +	{0x0034,0x03},   /* LCD Horizontal Non-Display Period Register */ +	{0x0035,0x01},   /* TFT FPLINE Start Position Register */ +	{0x0036,0x0B},   /* TFT FPLINE Pulse Width Register */ +	{0x0038,0xEF},   /* LCD Vertical Display Height Register 0 */ +	{0x0039,0x00},   /* LCD Vertical Display Height Register 1 */ +	{0x003A,0x2C},   /* LCD Vertical Non-Display Period Register */ +	{0x003B,0x0A},   /* TFT FPFRAME Start Position Register */ +	{0x003C,0x01},   /* TFT FPFRAME Pulse Width Register */ +	{0x0040,0x02},   /* LCD Display Mode Register */ +	{0x0041,0x00},   /* LCD Miscellaneous Register */ +	{0x0042,0x00},   /* LCD Display Start Address Register 0 */ +	{0x0043,0x00},   /* LCD Display Start Address Register 1 */ +	{0x0044,0x00},   /* LCD Display Start Address Register 2 */ +	{0x0046,0x50},   /* LCD Memory Address Offset Register 0 */ +	{0x0047,0x00},   /* LCD Memory Address Offset Register 1 */ +	{0x0048,0x00},   /* LCD Pixel Panning Register */ +	{0x004A,0x00},   /* LCD Display FIFO High Threshold Control Register */ +	{0x004B,0x00},   /* LCD Display FIFO Low Threshold Control Register */ +	{0x0050,0x4F},   /* CRT/TV Horizontal Display Width Register */ +	{0x0052,0x13},   /* CRT/TV Horizontal Non-Display Period Register */ +	{0x0053,0x01},   /* CRT/TV HRTC Start Position Register */ +	{0x0054,0x0B},   /* CRT/TV HRTC Pulse Width Register */ +	{0x0056,0xDF},   /* CRT/TV Vertical Display Height Register 0 */ +	{0x0057,0x01},   /* CRT/TV Vertical Display Height Register 1 */ +	{0x0058,0x2B},   /* CRT/TV Vertical Non-Display Period Register */ +	{0x0059,0x09},   /* CRT/TV VRTC Start Position Register */ +	{0x005A,0x01},   /* CRT/TV VRTC Pulse Width Register */ +	{0x005B,0x10},   /* TV Output Control Register */ +	{0x0060,0x03},   /* CRT/TV Display Mode Register */ +	{0x0062,0x00},   /* CRT/TV Display Start Address Register 0 */ +	{0x0063,0x00},   /* CRT/TV Display Start Address Register 1 */ +	{0x0064,0x00},   /* CRT/TV Display Start Address Register 2 */ +	{0x0066,0x40},   /* CRT/TV Memory Address Offset Register 0 */ +	{0x0067,0x01},   /* CRT/TV Memory Address Offset Register 1 */ +	{0x0068,0x00},   /* CRT/TV Pixel Panning Register */ +	{0x006A,0x00},   /* CRT/TV Display FIFO High Threshold Control Register */ +	{0x006B,0x00},   /* CRT/TV Display FIFO Low Threshold Control Register */ +	{0x0070,0x00},   /* LCD Ink/Cursor Control Register */ +	{0x0071,0x01},   /* LCD Ink/Cursor Start Address Register */ +	{0x0072,0x00},   /* LCD Cursor X Position Register 0 */ +	{0x0073,0x00},   /* LCD Cursor X Position Register 1 */ +	{0x0074,0x00},   /* LCD Cursor Y Position Register 0 */ +	{0x0075,0x00},   /* LCD Cursor Y Position Register 1 */ +	{0x0076,0x00},   /* LCD Ink/Cursor Blue Color 0 Register */ +	{0x0077,0x00},   /* LCD Ink/Cursor Green Color 0 Register */ +	{0x0078,0x00},   /* LCD Ink/Cursor Red Color 0 Register */ +	{0x007A,0x1F},   /* LCD Ink/Cursor Blue Color 1 Register */ +	{0x007B,0x3F},   /* LCD Ink/Cursor Green Color 1 Register */ +	{0x007C,0x1F},   /* LCD Ink/Cursor Red Color 1 Register */ +	{0x007E,0x00},   /* LCD Ink/Cursor FIFO Threshold Register */ +	{0x0080,0x00},   /* CRT/TV Ink/Cursor Control Register */ +	{0x0081,0x01},   /* CRT/TV Ink/Cursor Start Address Register */ +	{0x0082,0x00},   /* CRT/TV Cursor X Position Register 0 */ +	{0x0083,0x00},   /* CRT/TV Cursor X Position Register 1 */ +	{0x0084,0x00},   /* CRT/TV Cursor Y Position Register 0 */ +	{0x0085,0x00},   /* CRT/TV Cursor Y Position Register 1 */ +	{0x0086,0x00},   /* CRT/TV Ink/Cursor Blue Color 0 Register */ +	{0x0087,0x00},   /* CRT/TV Ink/Cursor Green Color 0 Register */ +	{0x0088,0x00},   /* CRT/TV Ink/Cursor Red Color 0 Register */ +	{0x008A,0x1F},   /* CRT/TV Ink/Cursor Blue Color 1 Register */ +	{0x008B,0x3F},   /* CRT/TV Ink/Cursor Green Color 1 Register */ +	{0x008C,0x1F},   /* CRT/TV Ink/Cursor Red Color 1 Register */ +	{0x008E,0x00},   /* CRT/TV Ink/Cursor FIFO Threshold Register */ +	{0x0100,0x00},   /* BitBlt Control Register 0 */ +	{0x0101,0x00},   /* BitBlt Control Register 1 */ +	{0x0102,0x00},   /* BitBlt ROP Code/Color Expansion Register */ +	{0x0103,0x00},   /* BitBlt Operation Register */ +	{0x0104,0x00},   /* BitBlt Source Start Address Register 0 */ +	{0x0105,0x00},   /* BitBlt Source Start Address Register 1 */ +	{0x0106,0x00},   /* BitBlt Source Start Address Register 2 */ +	{0x0108,0x00},   /* BitBlt Destination Start Address Register 0 */ +	{0x0109,0x00},   /* BitBlt Destination Start Address Register 1 */ +	{0x010A,0x00},   /* BitBlt Destination Start Address Register 2 */ +	{0x010C,0x00},   /* BitBlt Memory Address Offset Register 0 */ +	{0x010D,0x00},   /* BitBlt Memory Address Offset Register 1 */ +	{0x0110,0x00},   /* BitBlt Width Register 0 */ +	{0x0111,0x00},   /* BitBlt Width Register 1 */ +	{0x0112,0x00},   /* BitBlt Height Register 0 */ +	{0x0113,0x00},   /* BitBlt Height Register 1 */ +	{0x0114,0x00},   /* BitBlt Background Color Register 0 */ +	{0x0115,0x00},   /* BitBlt Background Color Register 1 */ +	{0x0118,0x00},   /* BitBlt Foreground Color Register 0 */ +	{0x0119,0x00},   /* BitBlt Foreground Color Register 1 */ +	{0x01E0,0x00},   /* Look-Up Table Mode Register */ +	{0x01E2,0x00},   /* Look-Up Table Address Register */ +	{0x01F0,0x10},   /* Power Save Configuration Register */ +	{0x01F1,0x00},   /* Power Save Status Register */ +	{0x01F4,0x00},   /* CPU-to-Memory Access Watchdog Timer Register */ +	{0x01FC,0x01},   /* Display Mode Register */ +}; diff --git a/roms/u-boot/board/esd/common/s1d13806_640_480_16bpp.h b/roms/u-boot/board/esd/common/s1d13806_640_480_16bpp.h new file mode 100644 index 00000000..38fc1a7e --- /dev/null +++ b/roms/u-boot/board/esd/common/s1d13806_640_480_16bpp.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2000,2001 Epson Research and Development, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + * + * File generated by S1D13806CFG.EXE + * Panel:  (active)   640x480 59Hz TFT Single 18-bit (PCLK=CLKI2=25.000MHz) + * Memory: Embedded SDRAM (MCLK=CLKI=49.152MHz) (BUSCLK=33.333MHz) + */ + +static S1D_REGS regs_13806_640_480_16bpp[] = +{ +	{0x0001,0x00},   /* Miscellaneous Register */ +	{0x01FC,0x00},   /* Display Mode Register */ +	{0x0004,0x18},   /* General IO Pins Configuration Register 0 */ +	{0x0005,0x00},   /* General IO Pins Configuration Register 1 */ +	{0x0008,0x18},   /* General IO Pins Control Register 0 */ +	{0x0009,0x00},   /* General IO Pins Control Register 1 */ +	{0x0010,0x00},   /* Memory Clock Configuration Register */ +	{0x0014,0x02},   /* LCD Pixel Clock Configuration Register */ +	{0x0018,0x02},   /* CRT/TV Pixel Clock Configuration Register */ +	{0x001C,0x02},   /* MediaPlug Clock Configuration Register */ +	{0x001E,0x01},   /* CPU To Memory Wait State Select Register */ +	{0x0021,0x03},   /* DRAM Refresh Rate Register */ +	{0x002A,0x00},   /* DRAM Timings Control Register 0 */ +	{0x002B,0x01},   /* DRAM Timings Control Register 1 */ +	{0x0020,0x80},   /* Memory Configuration Register */ +	{0x0030,0x25},   /* Panel Type Register */ +	{0x0031,0x00},   /* MOD Rate Register */ +	{0x0032,0x4F},   /* LCD Horizontal Display Width Register */ +	{0x0034,0x13},   /* LCD Horizontal Non-Display Period Register */ +	{0x0035,0x00},   /* TFT FPLINE Start Position Register */ +	{0x0036,0x0B},   /* TFT FPLINE Pulse Width Register */ +	{0x0038,0xDF},   /* LCD Vertical Display Height Register 0 */ +	{0x0039,0x01},   /* LCD Vertical Display Height Register 1 */ +	{0x003A,0x24},   /* LCD Vertical Non-Display Period Register */ +	{0x003B,0x00},   /* TFT FPFRAME Start Position Register */ +	{0x003C,0x01},   /* TFT FPFRAME Pulse Width Register */ +	{0x0040,0x05},   /* LCD Display Mode Register */ +	{0x0041,0x00},   /* LCD Miscellaneous Register */ +	{0x0042,0x00},   /* LCD Display Start Address Register 0 */ +	{0x0043,0x00},   /* LCD Display Start Address Register 1 */ +	{0x0044,0x00},   /* LCD Display Start Address Register 2 */ +	{0x0046,0x80},   /* LCD Memory Address Offset Register 0 */ +	{0x0047,0x02},   /* LCD Memory Address Offset Register 1 */ +	{0x0048,0x00},   /* LCD Pixel Panning Register */ +	{0x004A,0x00},   /* LCD Display FIFO High Threshold Control Register */ +	{0x004B,0x00},   /* LCD Display FIFO Low Threshold Control Register */ +	{0x0050,0x4F},   /* CRT/TV Horizontal Display Width Register */ +	{0x0052,0x13},   /* CRT/TV Horizontal Non-Display Period Register */ +	{0x0053,0x01},   /* CRT/TV HRTC Start Position Register */ +	{0x0054,0x0B},   /* CRT/TV HRTC Pulse Width Register */ +	{0x0056,0xDF},   /* CRT/TV Vertical Display Height Register 0 */ +	{0x0057,0x01},   /* CRT/TV Vertical Display Height Register 1 */ +	{0x0058,0x2B},   /* CRT/TV Vertical Non-Display Period Register */ +	{0x0059,0x09},   /* CRT/TV VRTC Start Position Register */ +	{0x005A,0x01},   /* CRT/TV VRTC Pulse Width Register */ +	{0x005B,0x10},   /* TV Output Control Register */ +	{0x0060,0x05},   /* CRT/TV Display Mode Register */ +	{0x0062,0x00},   /* CRT/TV Display Start Address Register 0 */ +	{0x0063,0x00},   /* CRT/TV Display Start Address Register 1 */ +	{0x0064,0x00},   /* CRT/TV Display Start Address Register 2 */ +	{0x0066,0x80},   /* CRT/TV Memory Address Offset Register 0 */ +	{0x0067,0x02},   /* CRT/TV Memory Address Offset Register 1 */ +	{0x0068,0x00},   /* CRT/TV Pixel Panning Register */ +	{0x006A,0x00},   /* CRT/TV Display FIFO High Threshold Control Register */ +	{0x006B,0x00},   /* CRT/TV Display FIFO Low Threshold Control Register */ +	{0x0070,0x00},   /* LCD Ink/Cursor Control Register */ +	{0x0071,0x01},   /* LCD Ink/Cursor Start Address Register */ +	{0x0072,0x00},   /* LCD Cursor X Position Register 0 */ +	{0x0073,0x00},   /* LCD Cursor X Position Register 1 */ +	{0x0074,0x00},   /* LCD Cursor Y Position Register 0 */ +	{0x0075,0x00},   /* LCD Cursor Y Position Register 1 */ +	{0x0076,0x00},   /* LCD Ink/Cursor Blue Color 0 Register */ +	{0x0077,0x00},   /* LCD Ink/Cursor Green Color 0 Register */ +	{0x0078,0x00},   /* LCD Ink/Cursor Red Color 0 Register */ +	{0x007A,0x1F},   /* LCD Ink/Cursor Blue Color 1 Register */ +	{0x007B,0x3F},   /* LCD Ink/Cursor Green Color 1 Register */ +	{0x007C,0x1F},   /* LCD Ink/Cursor Red Color 1 Register */ +	{0x007E,0x00},   /* LCD Ink/Cursor FIFO Threshold Register */ +	{0x0080,0x00},   /* CRT/TV Ink/Cursor Control Register */ +	{0x0081,0x01},   /* CRT/TV Ink/Cursor Start Address Register */ +	{0x0082,0x00},   /* CRT/TV Cursor X Position Register 0 */ +	{0x0083,0x00},   /* CRT/TV Cursor X Position Register 1 */ +	{0x0084,0x00},   /* CRT/TV Cursor Y Position Register 0 */ +	{0x0085,0x00},   /* CRT/TV Cursor Y Position Register 1 */ +	{0x0086,0x00},   /* CRT/TV Ink/Cursor Blue Color 0 Register */ +	{0x0087,0x00},   /* CRT/TV Ink/Cursor Green Color 0 Register */ +	{0x0088,0x00},   /* CRT/TV Ink/Cursor Red Color 0 Register */ +	{0x008A,0x1F},   /* CRT/TV Ink/Cursor Blue Color 1 Register */ +	{0x008B,0x3F},   /* CRT/TV Ink/Cursor Green Color 1 Register */ +	{0x008C,0x1F},   /* CRT/TV Ink/Cursor Red Color 1 Register */ +	{0x008E,0x00},   /* CRT/TV Ink/Cursor FIFO Threshold Register */ +	{0x0100,0x00},   /* BitBlt Control Register 0 */ +	{0x0101,0x00},   /* BitBlt Control Register 1 */ +	{0x0102,0x00},   /* BitBlt ROP Code/Color Expansion Register */ +	{0x0103,0x00},   /* BitBlt Operation Register */ +	{0x0104,0x00},   /* BitBlt Source Start Address Register 0 */ +	{0x0105,0x00},   /* BitBlt Source Start Address Register 1 */ +	{0x0106,0x00},   /* BitBlt Source Start Address Register 2 */ +	{0x0108,0x00},   /* BitBlt Destination Start Address Register 0 */ +	{0x0109,0x00},   /* BitBlt Destination Start Address Register 1 */ +	{0x010A,0x00},   /* BitBlt Destination Start Address Register 2 */ +	{0x010C,0x00},   /* BitBlt Memory Address Offset Register 0 */ +	{0x010D,0x00},   /* BitBlt Memory Address Offset Register 1 */ +	{0x0110,0x00},   /* BitBlt Width Register 0 */ +	{0x0111,0x00},   /* BitBlt Width Register 1 */ +	{0x0112,0x00},   /* BitBlt Height Register 0 */ +	{0x0113,0x00},   /* BitBlt Height Register 1 */ +	{0x0114,0x00},   /* BitBlt Background Color Register 0 */ +	{0x0115,0x00},   /* BitBlt Background Color Register 1 */ +	{0x0118,0x00},   /* BitBlt Foreground Color Register 0 */ +	{0x0119,0x00},   /* BitBlt Foreground Color Register 1 */ +	{0x01E0,0x00},   /* Look-Up Table Mode Register */ +	{0x01E2,0x00},   /* Look-Up Table Address Register */ +	{0x01F0,0x10},   /* Power Save Configuration Register */ +	{0x01F1,0x00},   /* Power Save Status Register */ +	{0x01F4,0x00},   /* CPU-to-Memory Access Watchdog Timer Register */ +	{0x01FC,0x01},   /* Display Mode Register */ +}; diff --git a/roms/u-boot/board/esd/common/xilinx_jtag/lenval.c b/roms/u-boot/board/esd/common/xilinx_jtag/lenval.c new file mode 100644 index 00000000..5405efbc --- /dev/null +++ b/roms/u-boot/board/esd/common/xilinx_jtag/lenval.c @@ -0,0 +1,201 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/*******************************************************/ +/* file: lenval.c                                      */ +/* abstract:  This file contains routines for using    */ +/*            the lenVal data structure.               */ +/*******************************************************/ + +#include <common.h> +#include <asm/processor.h> + +#include "lenval.h" +#include "ports.h" + + +/***************************************************************************** + * Function:     value + * Description:  Extract the long value from the lenval array. + * Parameters:   plvValue    - ptr to lenval. + * Returns:      long        - the extracted value. + *****************************************************************************/ +long value( lenVal*     plvValue ) +{ +	long    lValue;         /* result to hold the accumulated result */ +	short   sIndex; + +	lValue  = 0; +	for ( sIndex = 0; sIndex < plvValue->len ; ++sIndex ) +	{ +		lValue <<= 8;                       /* shift the accumulated result */ +		lValue |= plvValue->val[ sIndex];   /* get the last byte first */ +	} + +	return( lValue ); +} + +/***************************************************************************** + * Function:     initLenVal + * Description:  Initialize the lenval array with the given value. + *               Assumes lValue is less than 256. + * Parameters:   plv         - ptr to lenval. + *               lValue      - the value to set. + * Returns:      void. + *****************************************************************************/ +void initLenVal( lenVal*    plv, +		 long       lValue ) +{ +	plv->len    = 1; +	plv->val[0] = (unsigned char)lValue; +} + +/***************************************************************************** + * Function:     EqualLenVal + * Description:  Compare two lenval arrays with an optional mask. + * Parameters:   plvTdoExpected  - ptr to lenval #1. + *               plvTdoCaptured  - ptr to lenval #2. + *               plvTdoMask      - optional ptr to mask (=0 if no mask). + * Returns:      short   - 0 = mismatch; 1 = equal. + *****************************************************************************/ +short EqualLenVal( lenVal*  plvTdoExpected, +		   lenVal*  plvTdoCaptured, +		   lenVal*  plvTdoMask ) +{ +	short           sEqual; +	short           sIndex; +	unsigned char   ucByteVal1; +	unsigned char   ucByteVal2; +	unsigned char   ucByteMask; + +	sEqual  = 1; +	sIndex  = plvTdoExpected->len; + +	while ( sEqual && sIndex-- ) +	{ +		ucByteVal1  = plvTdoExpected->val[ sIndex ]; +		ucByteVal2  = plvTdoCaptured->val[ sIndex ]; +		if ( plvTdoMask ) +		{ +			ucByteMask  = plvTdoMask->val[ sIndex ]; +			ucByteVal1  &= ucByteMask; +			ucByteVal2  &= ucByteMask; +		} +		if ( ucByteVal1 != ucByteVal2 ) +		{ +			sEqual  = 0; +		} +	} + +	return( sEqual ); +} + + +/***************************************************************************** + * Function:     RetBit + * Description:  return the (byte, bit) of lv (reading from left to right). + * Parameters:   plv     - ptr to lenval. + *               iByte   - the byte to get the bit from. + *               iBit    - the bit number (0=msb) + * Returns:      short   - the bit value. + *****************************************************************************/ +short RetBit( lenVal*   plv, +	      int       iByte, +	      int       iBit ) +{ +	/* assert( ( iByte >= 0 ) && ( iByte < plv->len ) ); */ +	/* assert( ( iBit >= 0 ) && ( iBit < 8 ) ); */ +	return( (short)( ( plv->val[ iByte ] >> ( 7 - iBit ) ) & 0x1 ) ); +} + +/***************************************************************************** + * Function:     SetBit + * Description:  set the (byte, bit) of lv equal to val + * Example:      SetBit("00000000",byte, 1) equals "01000000". + * Parameters:   plv     - ptr to lenval. + *               iByte   - the byte to get the bit from. + *               iBit    - the bit number (0=msb). + *               sVal    - the bit value to set. + * Returns:      void. + *****************************************************************************/ +void SetBit( lenVal*    plv, +	     int        iByte, +	     int        iBit, +	     short      sVal ) +{ +	unsigned char   ucByteVal; +	unsigned char   ucBitMask; + +	ucBitMask   = (unsigned char)(1 << ( 7 - iBit )); +	ucByteVal   = (unsigned char)(plv->val[ iByte ] & (~ucBitMask)); + +	if ( sVal ) +	{ +		ucByteVal   |= ucBitMask; +	} +	plv->val[ iByte ]   = ucByteVal; +} + +/***************************************************************************** + * Function:     AddVal + * Description:  add val1 to val2 and store in resVal; + *               assumes val1 and val2  are of equal length. + * Parameters:   plvResVal   - ptr to result. + *               plvVal1     - ptr of addendum. + *               plvVal2     - ptr of addendum. + * Returns:      void. + *****************************************************************************/ +void addVal( lenVal*    plvResVal, +	     lenVal*    plvVal1, +	     lenVal*    plvVal2 ) +{ +	unsigned char   ucCarry; +	unsigned short  usSum; +	unsigned short  usVal1; +	unsigned short  usVal2; +	short           sIndex; + +	plvResVal->len  = plvVal1->len;         /* set up length of result */ + +	/* start at least significant bit and add bytes    */ +	ucCarry = 0; +	sIndex  = plvVal1->len; +	while ( sIndex-- ) +	{ +		usVal1  = plvVal1->val[ sIndex ];   /* i'th byte of val1 */ +		usVal2  = plvVal2->val[ sIndex ];   /* i'th byte of val2 */ + +		/* add the two bytes plus carry from previous addition */ +		usSum   = (unsigned short)( usVal1 + usVal2 + ucCarry ); + +		/* set up carry for next byte */ +		ucCarry = (unsigned char)( ( usSum > 255 ) ? 1 : 0 ); + +		/* set the i'th byte of the result */ +		plvResVal->val[ sIndex ]    = (unsigned char)usSum; +	} +} + +/***************************************************************************** + * Function:     readVal + * Description:  read from XSVF numBytes bytes of data into x. + * Parameters:   plv         - ptr to lenval in which to put the bytes read. + *               sNumBytes   - the number of bytes to read. + * Returns:      void. + *****************************************************************************/ +void readVal( lenVal*   plv, +	      short     sNumBytes ) +{ +	unsigned char*  pucVal; + +	plv->len    = sNumBytes;        /* set the length of the lenVal        */ +	for ( pucVal = plv->val; sNumBytes; --sNumBytes, ++pucVal ) +	{ +		/* read a byte of data into the lenVal */ +		readByte( pucVal ); +	} +} diff --git a/roms/u-boot/board/esd/common/xilinx_jtag/lenval.h b/roms/u-boot/board/esd/common/xilinx_jtag/lenval.h new file mode 100644 index 00000000..3273eec4 --- /dev/null +++ b/roms/u-boot/board/esd/common/xilinx_jtag/lenval.h @@ -0,0 +1,63 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/*******************************************************/ +/* file: lenval.h                                      */ +/* abstract:  This file contains a description of the  */ +/*            data structure "lenval".                 */ +/*******************************************************/ + +#ifndef lenval_dot_h +#define lenval_dot_h + +/* the lenVal structure is a byte oriented type used to store an */ +/* arbitrary length binary value. As an example, the hex value   */ +/* 0x0e3d is represented as a lenVal with len=2 (since 2 bytes   */ +/* and val[0]=0e and val[1]=3d.  val[2-MAX_LEN] are undefined    */ + +/* maximum length (in bytes) of value to read in        */ +/* this needs to be at least 4, and longer than the     */ +/* length of the longest SDR instruction.  If there is, */ +/* only 1 device in the chain, MAX_LEN must be at least */ +/* ceil(27/8) == 4.  For 6 devices in a chain, MAX_LEN  */ +/* must be 5, for 14 devices MAX_LEN must be 6, for 20  */ +/* devices MAX_LEN must be 7, etc..                     */ +/* You can safely set MAX_LEN to a smaller number if you*/ +/* know how many devices will be in your chain.         */ +#define MAX_LEN 7000 + + +typedef struct var_len_byte +{ +	short len;   /* number of chars in this value */ +	unsigned char val[MAX_LEN+1];  /* bytes of data */ +} lenVal; + + +/* return the long representation of a lenVal */ +extern long value(lenVal *x); + +/* set lenVal equal to value */ +extern void initLenVal(lenVal *x, long value); + +/* check if expected equals actual (taking the mask into account) */ +extern short EqualLenVal(lenVal *expected, lenVal *actual, lenVal *mask); + +/* add val1+val2 and put the result in resVal */ +extern void addVal(lenVal *resVal, lenVal *val1, lenVal *val2); + +/* return the (byte, bit) of lv (reading from left to right) */ +extern short RetBit(lenVal *lv, int byte, int bit); + +/* set the (byte, bit) of lv equal to val (e.g. SetBit("00000000",byte, 1) +   equals "01000000" */ +extern void SetBit(lenVal *lv, int byte, int bit, short val); + +/* read from XSVF numBytes bytes of data into x */ +extern void  readVal(lenVal *x, short numBytes); + +#endif diff --git a/roms/u-boot/board/esd/common/xilinx_jtag/micro.c b/roms/u-boot/board/esd/common/xilinx_jtag/micro.c new file mode 100644 index 00000000..556636c5 --- /dev/null +++ b/roms/u-boot/board/esd/common/xilinx_jtag/micro.c @@ -0,0 +1,1854 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/***************************************************************************** + * file:         micro.c + * abstract:     This file contains the function, xsvfExecute(), + *               call for interpreting the XSVF commands. + * Usage:        Call xsvfExecute() to process XSVF data. + *               The XSVF data is retrieved by readByte() in ports.c + *               Remove the main function if you already have one. + * Options:      XSVF_SUPPORT_COMPRESSION + *                   This define supports the XC9500/XL compression scheme. + *                   This define adds support for XSDRINC and XSETSDRMASKS. + *               XSVF_SUPPORT_ERRORCODES + *                   This define causes the xsvfExecute function to return + *                   an error code for specific errors.  See error codes below. + *                   If this is not defined, the return value defaults to the + *                   legacy values for backward compatibility: + *                   1 = success;  0 = failure. + * Debugging:    DEBUG_MODE (Legacy name) + *               Define DEBUG_MODE to compile with debugging features. + *               Both micro.c and ports.c must be compiled with the DEBUG_MODE + *               defined to enable the standalone main implementation in + *               micro.c that reads XSVF from a file. + * History:      v2.00   - Original XSVF implementation. + *               v4.04   - Added delay at end of XSIR for XC18v00 support. + *                         Added new commands for CoolRunner support: + *                         XSTATE, XENDIR, XENDDR + *               v4.05   - Cleanup micro.c but leave ports.c intact. + *               v4.06   - Fix xsvfGotoTapState for retry transition. + *               v4.07   - Update example waitTime implementations for + *                         compatibility with Virtex-II. + *               v4.10   - Add new XSIR2 command that supports a 2-byte + *                         IR-length parameter for IR shifts > 255 bits. + *               v4.11   - No change.  Update version to match SVF2XSVF xlator. + *               v4.14   - Added XCOMMENT. + *               v5.00   - Improve XSTATE support. + *                         Added XWAIT. + *****************************************************************************/ + +#include <common.h> +#include <command.h> +#include <asm/processor.h> + +#include "micro.h" +#include "lenval.h" +#include "ports.h" + +const unsigned char *xsvfdata; + +/*============================================================================ + * XSVF #define + ============================================================================*/ + +#define XSVF_VERSION    "5.00" + +/***************************************************************************** + * Define:       XSVF_SUPPORT_COMPRESSION + * Description:  Define this to support the XC9500/XL XSVF data compression + *               scheme. + *               Code size can be reduced by NOT supporting this feature. + *               However, you must use the -nc (no compress) option when + *               translating SVF to XSVF using the SVF2XSVF translator. + *               Corresponding, uncompressed XSVF may be larger. + *****************************************************************************/ +#ifndef XSVF_SUPPORT_COMPRESSION +#define XSVF_SUPPORT_COMPRESSION    1 +#endif + +/***************************************************************************** + * Define:       XSVF_SUPPORT_ERRORCODES + * Description:  Define this to support the new XSVF error codes. + *               (The original XSVF player just returned 1 for success and + *               0 for an unspecified failure.) + *****************************************************************************/ +#ifndef XSVF_SUPPORT_ERRORCODES +#define XSVF_SUPPORT_ERRORCODES     1 +#endif + +#ifdef  XSVF_SUPPORT_ERRORCODES +#define XSVF_ERRORCODE(errorCode)   errorCode +#else   /* Use legacy error code */ +#define XSVF_ERRORCODE(errorCode)   ((errorCode==XSVF_ERROR_NONE)?1:0) +#endif  /* XSVF_SUPPORT_ERRORCODES */ + + +/*============================================================================ + * DEBUG_MODE #define + ============================================================================*/ +#define DEBUG_MODE + +#ifdef  DEBUG_MODE +#define XSVFDBG_PRINTF(iDebugLevel,pzFormat) \ +		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \ +		    printf( pzFormat ); } +#define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) \ +		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \ +		    printf( pzFormat, arg1 ); } +#define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) \ +		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \ +		    printf( pzFormat, arg1, arg2 ); } +#define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) \ +		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \ +		    printf( pzFormat, arg1, arg2, arg3 ); } +#define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) \ +		{ if ( xsvf_iDebugLevel >= iDebugLevel ) \ +		    xsvfPrintLenVal(plenVal); } +#else   /* !DEBUG_MODE */ +#define XSVFDBG_PRINTF(iDebugLevel,pzFormat) +#define XSVFDBG_PRINTF1(iDebugLevel,pzFormat,arg1) +#define XSVFDBG_PRINTF2(iDebugLevel,pzFormat,arg1,arg2) +#define XSVFDBG_PRINTF3(iDebugLevel,pzFormat,arg1,arg2,arg3) +#define XSVFDBG_PRINTLENVAL(iDebugLevel,plenVal) +#endif  /* DEBUG_MODE */ + + +/*============================================================================ + * XSVF Type Declarations + ============================================================================*/ + +/***************************************************************************** + * Struct:       SXsvfInfo + * Description:  This structure contains all of the data used during the + *               execution of the XSVF.  Some data is persistent, predefined + *               information (e.g. lRunTestTime).  The bulk of this struct's + *               size is due to the lenVal structs (defined in lenval.h) + *               which contain buffers for the active shift data.  The MAX_LEN + *               #define in lenval.h defines the size of these buffers. + *               These buffers must be large enough to store the longest + *               shift data in your XSVF file.  For example: + *                   MAX_LEN >= ( longest_shift_data_in_bits / 8 ) + *               Because the lenVal struct dominates the space usage of this + *               struct, the rough size of this struct is: + *                   sizeof( SXsvfInfo ) ~= MAX_LEN * 7 (number of lenVals) + *               xsvfInitialize() contains initialization code for the data + *               in this struct. + *               xsvfCleanup() contains cleanup code for the data in this + *               struct. + *****************************************************************************/ +typedef struct tagSXsvfInfo +{ +	/* XSVF status information */ +	unsigned char   ucComplete;         /* 0 = running; 1 = complete */ +	unsigned char   ucCommand;          /* Current XSVF command byte */ +	long            lCommandCount;      /* Number of commands processed */ +	int             iErrorCode;         /* An error code. 0 = no error. */ + +	/* TAP state/sequencing information */ +	unsigned char   ucTapState;         /* Current TAP state */ +	unsigned char   ucEndIR;            /* ENDIR TAP state (See SVF) */ +	unsigned char   ucEndDR;            /* ENDDR TAP state (See SVF) */ + +	/* RUNTEST information */ +	unsigned char   ucMaxRepeat;        /* Max repeat loops (for xc9500/xl) */ +	long            lRunTestTime;       /* Pre-specified RUNTEST time (usec) */ + +	/* Shift Data Info and Buffers */ +	long            lShiftLengthBits;   /* Len. current shift data in bits */ +	short           sShiftLengthBytes;  /* Len. current shift data in bytes */ + +	lenVal          lvTdi;              /* Current TDI shift data */ +	lenVal          lvTdoExpected;      /* Expected TDO shift data */ +	lenVal          lvTdoCaptured;      /* Captured TDO shift data */ +	lenVal          lvTdoMask;          /* TDO mask: 0=dontcare; 1=compare */ + +#ifdef  XSVF_SUPPORT_COMPRESSION +	/* XSDRINC Data Buffers */ +	lenVal          lvAddressMask;      /* Address mask for XSDRINC */ +	lenVal          lvDataMask;         /* Data mask for XSDRINC */ +	lenVal          lvNextData;         /* Next data for XSDRINC */ +#endif  /* XSVF_SUPPORT_COMPRESSION */ +} SXsvfInfo; + +/* Declare pointer to functions that perform XSVF commands */ +typedef int (*TXsvfDoCmdFuncPtr)( SXsvfInfo* ); + +/*============================================================================ + * XSVF Command Bytes + ============================================================================*/ + +/* encodings of xsvf instructions */ +#define XCOMPLETE        0 +#define XTDOMASK         1 +#define XSIR             2 +#define XSDR             3 +#define XRUNTEST         4 +/* Reserved              5 */ +/* Reserved              6 */ +#define XREPEAT          7 +#define XSDRSIZE         8 +#define XSDRTDO          9 +#define XSETSDRMASKS     10 +#define XSDRINC          11 +#define XSDRB            12 +#define XSDRC            13 +#define XSDRE            14 +#define XSDRTDOB         15 +#define XSDRTDOC         16 +#define XSDRTDOE         17 +#define XSTATE           18         /* 4.00 */ +#define XENDIR           19         /* 4.04 */ +#define XENDDR           20         /* 4.04 */ +#define XSIR2            21         /* 4.10 */ +#define XCOMMENT         22         /* 4.14 */ +#define XWAIT            23         /* 5.00 */ +/* Insert new commands here */ +/* and add corresponding xsvfDoCmd function to xsvf_pfDoCmd below. */ +#define XLASTCMD         24         /* Last command marker */ + + +/*============================================================================ + * XSVF Command Parameter Values + ============================================================================*/ + +#define XSTATE_RESET     0          /* 4.00 parameter for XSTATE */ +#define XSTATE_RUNTEST   1          /* 4.00 parameter for XSTATE */ + +#define XENDXR_RUNTEST   0          /* 4.04 parameter for XENDIR/DR */ +#define XENDXR_PAUSE     1          /* 4.04 parameter for XENDIR/DR */ + +/* TAP states */ +#define XTAPSTATE_RESET     0x00 +#define XTAPSTATE_RUNTEST   0x01    /* a.k.a. IDLE */ +#define XTAPSTATE_SELECTDR  0x02 +#define XTAPSTATE_CAPTUREDR 0x03 +#define XTAPSTATE_SHIFTDR   0x04 +#define XTAPSTATE_EXIT1DR   0x05 +#define XTAPSTATE_PAUSEDR   0x06 +#define XTAPSTATE_EXIT2DR   0x07 +#define XTAPSTATE_UPDATEDR  0x08 +#define XTAPSTATE_IRSTATES  0x09    /* All IR states begin here */ +#define XTAPSTATE_SELECTIR  0x09 +#define XTAPSTATE_CAPTUREIR 0x0A +#define XTAPSTATE_SHIFTIR   0x0B +#define XTAPSTATE_EXIT1IR   0x0C +#define XTAPSTATE_PAUSEIR   0x0D +#define XTAPSTATE_EXIT2IR   0x0E +#define XTAPSTATE_UPDATEIR  0x0F + +/*============================================================================ + * XSVF Function Prototypes + ============================================================================*/ + +int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo );   /* Illegal command function */ +int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSIR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo ); +int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo ); +int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo ); +int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo ); +int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo ); +/* Insert new command functions here */ + +/*============================================================================ + * XSVF Global Variables + ============================================================================*/ + +/* Array of XSVF command functions.  Must follow command byte value order! */ +/* If your compiler cannot take this form, then convert to a switch statement*/ +TXsvfDoCmdFuncPtr   xsvf_pfDoCmd[]  = +{ +	xsvfDoXCOMPLETE,        /*  0 */ +	xsvfDoXTDOMASK,         /*  1 */ +	xsvfDoXSIR,             /*  2 */ +	xsvfDoXSDR,             /*  3 */ +	xsvfDoXRUNTEST,         /*  4 */ +	xsvfDoIllegalCmd,       /*  5 */ +	xsvfDoIllegalCmd,       /*  6 */ +	xsvfDoXREPEAT,          /*  7 */ +	xsvfDoXSDRSIZE,         /*  8 */ +	xsvfDoXSDRTDO,          /*  9 */ +#ifdef  XSVF_SUPPORT_COMPRESSION +	xsvfDoXSETSDRMASKS,     /* 10 */ +	xsvfDoXSDRINC,          /* 11 */ +#else +	xsvfDoIllegalCmd,       /* 10 */ +	xsvfDoIllegalCmd,       /* 11 */ +#endif  /* XSVF_SUPPORT_COMPRESSION */ +	xsvfDoXSDRBCE,          /* 12 */ +	xsvfDoXSDRBCE,          /* 13 */ +	xsvfDoXSDRBCE,          /* 14 */ +	xsvfDoXSDRTDOBCE,       /* 15 */ +	xsvfDoXSDRTDOBCE,       /* 16 */ +	xsvfDoXSDRTDOBCE,       /* 17 */ +	xsvfDoXSTATE,           /* 18 */ +	xsvfDoXENDXR,           /* 19 */ +	xsvfDoXENDXR,           /* 20 */ +	xsvfDoXSIR2,            /* 21 */ +	xsvfDoXCOMMENT,         /* 22 */ +	xsvfDoXWAIT             /* 23 */ +/* Insert new command functions here */ +}; + +#ifdef  DEBUG_MODE +char* xsvf_pzCommandName[]  = +{ +	"XCOMPLETE", +	"XTDOMASK", +	"XSIR", +	"XSDR", +	"XRUNTEST", +	"Reserved5", +	"Reserved6", +	"XREPEAT", +	"XSDRSIZE", +	"XSDRTDO", +	"XSETSDRMASKS", +	"XSDRINC", +	"XSDRB", +	"XSDRC", +	"XSDRE", +	"XSDRTDOB", +	"XSDRTDOC", +	"XSDRTDOE", +	"XSTATE", +	"XENDIR", +	"XENDDR", +	"XSIR2", +	"XCOMMENT", +	"XWAIT" +}; + +char*   xsvf_pzErrorName[]  = +{ +	"No error", +	"ERROR:  Unknown", +	"ERROR:  TDO mismatch", +	"ERROR:  TDO mismatch and exceeded max retries", +	"ERROR:  Unsupported XSVF command", +	"ERROR:  Illegal state specification", +	"ERROR:  Data overflows allocated MAX_LEN buffer size" +}; + +char*   xsvf_pzTapState[] = +{ +	"RESET",        /* 0x00 */ +	"RUNTEST/IDLE", /* 0x01 */ +	"DRSELECT",     /* 0x02 */ +	"DRCAPTURE",    /* 0x03 */ +	"DRSHIFT",      /* 0x04 */ +	"DREXIT1",      /* 0x05 */ +	"DRPAUSE",      /* 0x06 */ +	"DREXIT2",      /* 0x07 */ +	"DRUPDATE",     /* 0x08 */ +	"IRSELECT",     /* 0x09 */ +	"IRCAPTURE",    /* 0x0A */ +	"IRSHIFT",      /* 0x0B */ +	"IREXIT1",      /* 0x0C */ +	"IRPAUSE",      /* 0x0D */ +	"IREXIT2",      /* 0x0E */ +	"IRUPDATE"      /* 0x0F */ +}; +#endif  /* DEBUG_MODE */ + +/*#ifdef DEBUG_MODE	*/ +/*    FILE* in;   /XXX* Legacy DEBUG_MODE file pointer */ +int xsvf_iDebugLevel; +/*#endif /XXX* DEBUG_MODE */ + +/*============================================================================ + * Utility Functions + ============================================================================*/ + +/***************************************************************************** + * Function:     xsvfPrintLenVal + * Description:  Print the lenval value in hex. + * Parameters:   plv     - ptr to lenval. + * Returns:      void. + *****************************************************************************/ +#ifdef  DEBUG_MODE +void xsvfPrintLenVal( lenVal *plv ) +{ +	int i; + +	if ( plv ) +	{ +		printf( "0x" ); +		for ( i = 0; i < plv->len; ++i ) +		{ +			printf( "%02x", ((unsigned int)(plv->val[ i ])) ); +		} +	} +} +#endif  /* DEBUG_MODE */ + + +/***************************************************************************** + * Function:     xsvfInfoInit + * Description:  Initialize the xsvfInfo data. + * Parameters:   pXsvfInfo   - ptr to the XSVF info structure. + * Returns:      int         - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfInfoInit( SXsvfInfo* pXsvfInfo ) +{ +	XSVFDBG_PRINTF1( 4, "    sizeof( SXsvfInfo ) = %d bytes\n", +			 sizeof( SXsvfInfo ) ); + +	pXsvfInfo->ucComplete       = 0; +	pXsvfInfo->ucCommand        = XCOMPLETE; +	pXsvfInfo->lCommandCount    = 0; +	pXsvfInfo->iErrorCode       = XSVF_ERROR_NONE; +	pXsvfInfo->ucMaxRepeat      = 0; +	pXsvfInfo->ucTapState       = XTAPSTATE_RESET; +	pXsvfInfo->ucEndIR          = XTAPSTATE_RUNTEST; +	pXsvfInfo->ucEndDR          = XTAPSTATE_RUNTEST; +	pXsvfInfo->lShiftLengthBits = 0L; +	pXsvfInfo->sShiftLengthBytes= 0; +	pXsvfInfo->lRunTestTime     = 0L; + +	return( 0 ); +} + +/***************************************************************************** + * Function:     xsvfInfoCleanup + * Description:  Cleanup the xsvfInfo data. + * Parameters:   pXsvfInfo   - ptr to the XSVF info structure. + * Returns:      void. + *****************************************************************************/ +void xsvfInfoCleanup( SXsvfInfo* pXsvfInfo ) +{ +} + +/***************************************************************************** + * Function:     xsvfGetAsNumBytes + * Description:  Calculate the number of bytes the given number of bits + *               consumes. + * Parameters:   lNumBits    - the number of bits. + * Returns:      short       - the number of bytes to store the number of bits. + *****************************************************************************/ +short xsvfGetAsNumBytes( long lNumBits ) +{ +	return( (short)( ( lNumBits + 7L ) / 8L ) ); +} + +/***************************************************************************** + * Function:     xsvfTmsTransition + * Description:  Apply TMS and transition TAP controller by applying one TCK + *               cycle. + * Parameters:   sTms    - new TMS value. + * Returns:      void. + *****************************************************************************/ +void xsvfTmsTransition( short sTms ) +{ +	setPort( TMS, sTms ); +	setPort( TCK, 0 ); +	setPort( TCK, 1 ); +} + +/***************************************************************************** + * Function:     xsvfGotoTapState + * Description:  From the current TAP state, go to the named TAP state. + *               A target state of RESET ALWAYS causes TMS reset sequence. + *               All SVF standard stable state paths are supported. + *               All state transitions are supported except for the following + *               which cause an XSVF_ERROR_ILLEGALSTATE: + *                   - Target==DREXIT2;  Start!=DRPAUSE + *                   - Target==IREXIT2;  Start!=IRPAUSE + * Parameters:   pucTapState     - Current TAP state; returns final TAP state. + *               ucTargetState   - New target TAP state. + * Returns:      int             - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfGotoTapState( unsigned char*   pucTapState, +		      unsigned char    ucTargetState ) +{ +	int i; +	int iErrorCode; + +	iErrorCode  = XSVF_ERROR_NONE; +	if ( ucTargetState == XTAPSTATE_RESET ) +	{ +		/* If RESET, always perform TMS reset sequence to reset/sync TAPs */ +		xsvfTmsTransition( 1 ); +		for ( i = 0; i < 5; ++i ) +		{ +			setPort( TCK, 0 ); +			setPort( TCK, 1 ); +		} +		*pucTapState    = XTAPSTATE_RESET; +		XSVFDBG_PRINTF( 3, "   TMS Reset Sequence -> Test-Logic-Reset\n" ); +		XSVFDBG_PRINTF1( 3, "   TAP State = %s\n", +				 xsvf_pzTapState[ *pucTapState ] ); +	} else if ( ( ucTargetState != *pucTapState ) && +		  ( ( ( ucTargetState == XTAPSTATE_EXIT2DR ) && ( *pucTapState != XTAPSTATE_PAUSEDR ) ) || +		    ( ( ucTargetState == XTAPSTATE_EXIT2IR ) && ( *pucTapState != XTAPSTATE_PAUSEIR ) ) ) ) +	{ +		/* Trap illegal TAP state path specification */ +		iErrorCode      = XSVF_ERROR_ILLEGALSTATE; +	} else { +		if ( ucTargetState == *pucTapState ) +		{ +			/* Already in target state.  Do nothing except when in DRPAUSE +			   or in IRPAUSE to comply with SVF standard */ +			if ( ucTargetState == XTAPSTATE_PAUSEDR ) +			{ +				xsvfTmsTransition( 1 ); +				*pucTapState    = XTAPSTATE_EXIT2DR; +				XSVFDBG_PRINTF1( 3, "   TAP State = %s\n", +						 xsvf_pzTapState[ *pucTapState ] ); +			} +			else if ( ucTargetState == XTAPSTATE_PAUSEIR ) +			{ +				xsvfTmsTransition( 1 ); +				*pucTapState    = XTAPSTATE_EXIT2IR; +				XSVFDBG_PRINTF1( 3, "   TAP State = %s\n", +						 xsvf_pzTapState[ *pucTapState ] ); +			} +		} + +		/* Perform TAP state transitions to get to the target state */ +		while ( ucTargetState != *pucTapState ) +		{ +			switch ( *pucTapState ) +			{ +			case XTAPSTATE_RESET: +				xsvfTmsTransition( 0 ); +				*pucTapState    = XTAPSTATE_RUNTEST; +				break; +			case XTAPSTATE_RUNTEST: +				xsvfTmsTransition( 1 ); +				*pucTapState    = XTAPSTATE_SELECTDR; +				break; +			case XTAPSTATE_SELECTDR: +				if ( ucTargetState >= XTAPSTATE_IRSTATES ) +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_SELECTIR; +				} +				else +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_CAPTUREDR; +				} +				break; +			case XTAPSTATE_CAPTUREDR: +				if ( ucTargetState == XTAPSTATE_SHIFTDR ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_SHIFTDR; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_EXIT1DR; +				} +				break; +			case XTAPSTATE_SHIFTDR: +				xsvfTmsTransition( 1 ); +				*pucTapState    = XTAPSTATE_EXIT1DR; +				break; +			case XTAPSTATE_EXIT1DR: +				if ( ucTargetState == XTAPSTATE_PAUSEDR ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_PAUSEDR; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_UPDATEDR; +				} +				break; +			case XTAPSTATE_PAUSEDR: +				xsvfTmsTransition( 1 ); +				*pucTapState    = XTAPSTATE_EXIT2DR; +				break; +			case XTAPSTATE_EXIT2DR: +				if ( ucTargetState == XTAPSTATE_SHIFTDR ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_SHIFTDR; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_UPDATEDR; +				} +				break; +			case XTAPSTATE_UPDATEDR: +				if ( ucTargetState == XTAPSTATE_RUNTEST ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_RUNTEST; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_SELECTDR; +				} +				break; +			case XTAPSTATE_SELECTIR: +				xsvfTmsTransition( 0 ); +				*pucTapState    = XTAPSTATE_CAPTUREIR; +				break; +			case XTAPSTATE_CAPTUREIR: +				if ( ucTargetState == XTAPSTATE_SHIFTIR ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_SHIFTIR; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_EXIT1IR; +				} +				break; +			case XTAPSTATE_SHIFTIR: +				xsvfTmsTransition( 1 ); +				*pucTapState    = XTAPSTATE_EXIT1IR; +				break; +			case XTAPSTATE_EXIT1IR: +				if ( ucTargetState == XTAPSTATE_PAUSEIR ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_PAUSEIR; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_UPDATEIR; +				} +				break; +			case XTAPSTATE_PAUSEIR: +				xsvfTmsTransition( 1 ); +				*pucTapState    = XTAPSTATE_EXIT2IR; +				break; +			case XTAPSTATE_EXIT2IR: +				if ( ucTargetState == XTAPSTATE_SHIFTIR ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_SHIFTIR; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_UPDATEIR; +				} +				break; +			case XTAPSTATE_UPDATEIR: +				if ( ucTargetState == XTAPSTATE_RUNTEST ) +				{ +					xsvfTmsTransition( 0 ); +					*pucTapState    = XTAPSTATE_RUNTEST; +				} +				else +				{ +					xsvfTmsTransition( 1 ); +					*pucTapState    = XTAPSTATE_SELECTDR; +				} +				break; +			default: +				iErrorCode      = XSVF_ERROR_ILLEGALSTATE; +				*pucTapState    = ucTargetState;    /* Exit while loop */ +				break; +			} +			XSVFDBG_PRINTF1( 3, "   TAP State = %s\n", +					 xsvf_pzTapState[ *pucTapState ] ); +		} +	} + +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfShiftOnly + * Description:  Assumes that starting TAP state is SHIFT-DR or SHIFT-IR. + *               Shift the given TDI data into the JTAG scan chain. + *               Optionally, save the TDO data shifted out of the scan chain. + *               Last shift cycle is special:  capture last TDO, set last TDI, + *               but does not pulse TCK.  Caller must pulse TCK and optionally + *               set TMS=1 to exit shift state. + * Parameters:   lNumBits        - number of bits to shift. + *               plvTdi          - ptr to lenval for TDI data. + *               plvTdoCaptured  - ptr to lenval for storing captured TDO data. + *               iExitShift      - 1=exit at end of shift; 0=stay in Shift-DR. + * Returns:      void. + *****************************************************************************/ +void xsvfShiftOnly( long    lNumBits, +		    lenVal* plvTdi, +		    lenVal* plvTdoCaptured, +		    int     iExitShift ) +{ +	unsigned char*  pucTdi; +	unsigned char*  pucTdo; +	unsigned char   ucTdiByte; +	unsigned char   ucTdoByte; +	unsigned char   ucTdoBit; +	int             i; + +	/* assert( ( ( lNumBits + 7 ) / 8 ) == plvTdi->len ); */ + +	/* Initialize TDO storage len == TDI len */ +	pucTdo  = 0; +	if ( plvTdoCaptured ) +	{ +		plvTdoCaptured->len = plvTdi->len; +		pucTdo              = plvTdoCaptured->val + plvTdi->len; +	} + +	/* Shift LSB first.  val[N-1] == LSB.  val[0] == MSB. */ +	pucTdi  = plvTdi->val + plvTdi->len; +	while ( lNumBits ) +	{ +		/* Process on a byte-basis */ +		ucTdiByte   = (*(--pucTdi)); +		ucTdoByte   = 0; +		for ( i = 0; ( lNumBits && ( i < 8 ) ); ++i ) +		{ +			--lNumBits; +			if ( iExitShift && !lNumBits ) +			{ +				/* Exit Shift-DR state */ +				setPort( TMS, 1 ); +			} + +			/* Set the new TDI value */ +			setPort( TDI, (short)(ucTdiByte & 1) ); +			ucTdiByte   >>= 1; + +			/* Set TCK low */ +			setPort( TCK, 0 ); + +			if ( pucTdo ) +			{ +				/* Save the TDO value */ +				ucTdoBit    = readTDOBit(); +				ucTdoByte   |= ( ucTdoBit << i ); +			} + +			/* Set TCK high */ +			setPort( TCK, 1 ); +		} + +		/* Save the TDO byte value */ +		if ( pucTdo ) +		{ +			(*(--pucTdo))   = ucTdoByte; +		} +	} +} + +/***************************************************************************** + * Function:     xsvfShift + * Description:  Goes to the given starting TAP state. + *               Calls xsvfShiftOnly to shift in the given TDI data and + *               optionally capture the TDO data. + *               Compares the TDO captured data against the TDO expected + *               data. + *               If a data mismatch occurs, then executes the exception + *               handling loop upto ucMaxRepeat times. + * Parameters:   pucTapState     - Ptr to current TAP state. + *               ucStartState    - Starting shift state: Shift-DR or Shift-IR. + *               lNumBits        - number of bits to shift. + *               plvTdi          - ptr to lenval for TDI data. + *               plvTdoCaptured  - ptr to lenval for storing TDO data. + *               plvTdoExpected  - ptr to expected TDO data. + *               plvTdoMask      - ptr to TDO mask. + *               ucEndState      - state in which to end the shift. + *               lRunTestTime    - amount of time to wait after the shift. + *               ucMaxRepeat     - Maximum number of retries on TDO mismatch. + * Returns:      int             - 0 = success; otherwise TDO mismatch. + * Notes:        XC9500XL-only Optimization: + *               Skip the waitTime() if plvTdoMask->val[0:plvTdoMask->len-1] + *               is NOT all zeros and sMatch==1. + *****************************************************************************/ +int xsvfShift( unsigned char*   pucTapState, +	       unsigned char    ucStartState, +	       long             lNumBits, +	       lenVal*          plvTdi, +	       lenVal*          plvTdoCaptured, +	       lenVal*          plvTdoExpected, +	       lenVal*          plvTdoMask, +	       unsigned char    ucEndState, +	       long             lRunTestTime, +	       unsigned char    ucMaxRepeat ) +{ +	int             iErrorCode; +	int             iMismatch; +	unsigned char   ucRepeat; +	int             iExitShift; + +	iErrorCode  = XSVF_ERROR_NONE; +	iMismatch   = 0; +	ucRepeat    = 0; +	iExitShift  = ( ucStartState != ucEndState ); + +	XSVFDBG_PRINTF1( 3, "   Shift Length = %ld\n", lNumBits ); +	XSVFDBG_PRINTF( 4, "    TDI          = "); +	XSVFDBG_PRINTLENVAL( 4, plvTdi ); +	XSVFDBG_PRINTF( 4, "\n"); +	XSVFDBG_PRINTF( 4, "    TDO Expected = "); +	XSVFDBG_PRINTLENVAL( 4, plvTdoExpected ); +	XSVFDBG_PRINTF( 4, "\n"); + +	if ( !lNumBits ) +	{ +		/* Compatibility with XSVF2.00:  XSDR 0 = no shift, but wait in RTI */ +		if ( lRunTestTime ) +		{ +			/* Wait for prespecified XRUNTEST time */ +			xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST ); +			XSVFDBG_PRINTF1( 3, "   Wait = %ld usec\n", lRunTestTime ); +			waitTime( lRunTestTime ); +		} +	} +	else +	{ +		do +		{ +			/* Goto Shift-DR or Shift-IR */ +			xsvfGotoTapState( pucTapState, ucStartState ); + +			/* Shift TDI and capture TDO */ +			xsvfShiftOnly( lNumBits, plvTdi, plvTdoCaptured, iExitShift ); + +			if ( plvTdoExpected ) +			{ +				/* Compare TDO data to expected TDO data */ +				iMismatch   = !EqualLenVal( plvTdoExpected, +							    plvTdoCaptured, +							    plvTdoMask ); +			} + +			if ( iExitShift ) +			{ +				/* Update TAP state:  Shift->Exit */ +				++(*pucTapState); +				XSVFDBG_PRINTF1( 3, "   TAP State = %s\n", +						 xsvf_pzTapState[ *pucTapState ] ); + +				if ( iMismatch && lRunTestTime && ( ucRepeat < ucMaxRepeat ) ) +				{ +					XSVFDBG_PRINTF( 4, "    TDO Expected = "); +					XSVFDBG_PRINTLENVAL( 4, plvTdoExpected ); +					XSVFDBG_PRINTF( 4, "\n"); +					XSVFDBG_PRINTF( 4, "    TDO Captured = "); +					XSVFDBG_PRINTLENVAL( 4, plvTdoCaptured ); +					XSVFDBG_PRINTF( 4, "\n"); +					XSVFDBG_PRINTF( 4, "    TDO Mask     = "); +					XSVFDBG_PRINTLENVAL( 4, plvTdoMask ); +					XSVFDBG_PRINTF( 4, "\n"); +					XSVFDBG_PRINTF1( 3, "   Retry #%d\n", ( ucRepeat + 1 ) ); +					/* Do exception handling retry - ShiftDR only */ +					xsvfGotoTapState( pucTapState, XTAPSTATE_PAUSEDR ); +					/* Shift 1 extra bit */ +					xsvfGotoTapState( pucTapState, XTAPSTATE_SHIFTDR ); +					/* Increment RUNTEST time by an additional 25% */ +					lRunTestTime    += ( lRunTestTime >> 2 ); +				} +				else +				{ +					/* Do normal exit from Shift-XR */ +					xsvfGotoTapState( pucTapState, ucEndState ); +				} + +				if ( lRunTestTime ) +				{ +					/* Wait for prespecified XRUNTEST time */ +					xsvfGotoTapState( pucTapState, XTAPSTATE_RUNTEST ); +					XSVFDBG_PRINTF1( 3, "   Wait = %ld usec\n", lRunTestTime ); +					waitTime( lRunTestTime ); +				} +			} +		} while ( iMismatch && ( ucRepeat++ < ucMaxRepeat ) ); +	} + +	if ( iMismatch ) +	{ +		XSVFDBG_PRINTF( 1, " TDO Expected = "); +		XSVFDBG_PRINTLENVAL( 1, plvTdoExpected ); +		XSVFDBG_PRINTF( 1, "\n"); +		XSVFDBG_PRINTF( 1, " TDO Captured = "); +		XSVFDBG_PRINTLENVAL( 1, plvTdoCaptured ); +		XSVFDBG_PRINTF( 1, "\n"); +		XSVFDBG_PRINTF( 1, " TDO Mask     = "); +		XSVFDBG_PRINTLENVAL( 1, plvTdoMask ); +		XSVFDBG_PRINTF( 1, "\n"); +		if ( ucMaxRepeat && ( ucRepeat > ucMaxRepeat ) ) +		{ +			iErrorCode  = XSVF_ERROR_MAXRETRIES; +		} +		else +		{ +			iErrorCode  = XSVF_ERROR_TDOMISMATCH; +		} +	} + +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfBasicXSDRTDO + * Description:  Get the XSDRTDO parameters and execute the XSDRTDO command. + *               This is the common function for all XSDRTDO commands. + * Parameters:   pucTapState         - Current TAP state. + *               lShiftLengthBits    - number of bits to shift. + *               sShiftLengthBytes   - number of bytes to read. + *               plvTdi              - ptr to lenval for TDI data. + *               lvTdoCaptured       - ptr to lenval for storing TDO data. + *               iEndState           - state in which to end the shift. + *               lRunTestTime        - amount of time to wait after the shift. + *               ucMaxRepeat         - maximum xc9500/xl retries. + * Returns:      int                 - 0 = success; otherwise TDO mismatch. + *****************************************************************************/ +int xsvfBasicXSDRTDO( unsigned char*    pucTapState, +		      long              lShiftLengthBits, +		      short             sShiftLengthBytes, +		      lenVal*           plvTdi, +		      lenVal*           plvTdoCaptured, +		      lenVal*           plvTdoExpected, +		      lenVal*           plvTdoMask, +		      unsigned char     ucEndState, +		      long              lRunTestTime, +		      unsigned char     ucMaxRepeat ) +{ +	readVal( plvTdi, sShiftLengthBytes ); +	if ( plvTdoExpected ) +	{ +		readVal( plvTdoExpected, sShiftLengthBytes ); +	} +	return( xsvfShift( pucTapState, XTAPSTATE_SHIFTDR, lShiftLengthBits, +			   plvTdi, plvTdoCaptured, plvTdoExpected, plvTdoMask, +			   ucEndState, lRunTestTime, ucMaxRepeat ) ); +} + +/***************************************************************************** + * Function:     xsvfDoSDRMasking + * Description:  Update the data value with the next XSDRINC data and address. + * Example:      dataVal=0x01ff, nextData=0xab, addressMask=0x0100, + *               dataMask=0x00ff, should set dataVal to 0x02ab + * Parameters:   plvTdi          - The current TDI value. + *               plvNextData     - the next data value. + *               plvAddressMask  - the address mask. + *               plvDataMask     - the data mask. + * Returns:      void. + *****************************************************************************/ +#ifdef  XSVF_SUPPORT_COMPRESSION +void xsvfDoSDRMasking( lenVal*  plvTdi, +		       lenVal*  plvNextData, +		       lenVal*  plvAddressMask, +		       lenVal*  plvDataMask ) +{ +	int             i; +	unsigned char   ucTdi; +	unsigned char   ucTdiMask; +	unsigned char   ucDataMask; +	unsigned char   ucNextData; +	unsigned char   ucNextMask; +	short           sNextData; + +	/* add the address Mask to dataVal and return as a new dataVal */ +	addVal( plvTdi, plvTdi, plvAddressMask ); + +	ucNextData  = 0; +	ucNextMask  = 0; +	sNextData   = plvNextData->len; +	for ( i = plvDataMask->len - 1; i >= 0; --i ) +	{ +		/* Go through data mask in reverse order looking for mask (1) bits */ +		ucDataMask  = plvDataMask->val[ i ]; +		if ( ucDataMask ) +		{ +			/* Retrieve the corresponding TDI byte value */ +			ucTdi       = plvTdi->val[ i ]; + +			/* For each bit in the data mask byte, look for 1's */ +			ucTdiMask   = 1; +			while ( ucDataMask ) +			{ +				if ( ucDataMask & 1 ) +				{ +					if ( !ucNextMask ) +					{ +						/* Get the next data byte */ +						ucNextData  = plvNextData->val[ --sNextData ]; +						ucNextMask  = 1; +					} + +					/* Set or clear the data bit according to the next data */ +					if ( ucNextData & ucNextMask ) +					{ +						ucTdi   |= ucTdiMask;       /* Set bit */ +					} +					else +					{ +						ucTdi   &= ( ~ucTdiMask );  /* Clear bit */ +					} + +					/* Update the next data */ +					ucNextMask  <<= 1; +				} +				ucTdiMask   <<= 1; +				ucDataMask  >>= 1; +			} + +			/* Update the TDI value */ +			plvTdi->val[ i ]    = ucTdi; +		} +	} +} +#endif  /* XSVF_SUPPORT_COMPRESSION */ + +/*============================================================================ + * XSVF Command Functions (type = TXsvfDoCmdFuncPtr) + * These functions update pXsvfInfo->iErrorCode only on an error. + * Otherwise, the error code is left alone. + * The function returns the error code from the function. + ============================================================================*/ + +/***************************************************************************** + * Function:     xsvfDoIllegalCmd + * Description:  Function place holder for illegal/unsupported commands. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoIllegalCmd( SXsvfInfo* pXsvfInfo ) +{ +	XSVFDBG_PRINTF2( 0, "ERROR:  Encountered unsupported command #%d (%s)\n", +			 ((unsigned int)(pXsvfInfo->ucCommand)), +			 ((pXsvfInfo->ucCommand < XLASTCMD) +			  ? (xsvf_pzCommandName[pXsvfInfo->ucCommand]) +			  : "Unknown") ); +	pXsvfInfo->iErrorCode   = XSVF_ERROR_ILLEGALCMD; +	return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXCOMPLETE + * Description:  XCOMPLETE (no parameters) + *               Update complete status for XSVF player. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXCOMPLETE( SXsvfInfo* pXsvfInfo ) +{ +	pXsvfInfo->ucComplete   = 1; +	return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function:     xsvfDoXTDOMASK + * Description:  XTDOMASK <lenVal.TdoMask[XSDRSIZE]> + *               Prespecify the TDO compare mask. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXTDOMASK( SXsvfInfo* pXsvfInfo ) +{ +	readVal( &(pXsvfInfo->lvTdoMask), pXsvfInfo->sShiftLengthBytes ); +	XSVFDBG_PRINTF( 4, "    TDO Mask     = "); +	XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvTdoMask) ); +	XSVFDBG_PRINTF( 4, "\n"); +	return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function:     xsvfDoXSIR + * Description:  XSIR <(byte)shiftlen> <lenVal.TDI[shiftlen]> + *               Get the instruction and shift the instruction into the TAP. + *               If prespecified XRUNTEST!=0, goto RUNTEST and wait after + *               the shift for XRUNTEST usec. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSIR( SXsvfInfo* pXsvfInfo ) +{ +	unsigned char   ucShiftIrBits; +	short           sShiftIrBytes; +	int             iErrorCode; + +	/* Get the shift length and store */ +	readByte( &ucShiftIrBits ); +	sShiftIrBytes   = xsvfGetAsNumBytes( ucShiftIrBits ); +	XSVFDBG_PRINTF1( 3, "   XSIR length = %d\n", +			 ((unsigned int)ucShiftIrBits) ); + +	if ( sShiftIrBytes > MAX_LEN ) +	{ +		iErrorCode  = XSVF_ERROR_DATAOVERFLOW; +	} +	else +	{ +		/* Get and store instruction to shift in */ +		readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( ucShiftIrBits ) ); + +		/* Shift the data */ +		iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR, +					 ucShiftIrBits, &(pXsvfInfo->lvTdi), +					 /*plvTdoCaptured*/0, /*plvTdoExpected*/0, +					 /*plvTdoMask*/0, pXsvfInfo->ucEndIR, +					 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 ); +	} + +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXSIR2 + * Description:  XSIR <(2-byte)shiftlen> <lenVal.TDI[shiftlen]> + *               Get the instruction and shift the instruction into the TAP. + *               If prespecified XRUNTEST!=0, goto RUNTEST and wait after + *               the shift for XRUNTEST usec. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSIR2( SXsvfInfo* pXsvfInfo ) +{ +	long            lShiftIrBits; +	short           sShiftIrBytes; +	int             iErrorCode; + +	/* Get the shift length and store */ +	readVal( &(pXsvfInfo->lvTdi), 2 ); +	lShiftIrBits    = value( &(pXsvfInfo->lvTdi) ); +	sShiftIrBytes   = xsvfGetAsNumBytes( lShiftIrBits ); +	XSVFDBG_PRINTF1( 3, "   XSIR2 length = %d\n", (int)lShiftIrBits); + +	if ( sShiftIrBytes > MAX_LEN ) +	{ +		iErrorCode  = XSVF_ERROR_DATAOVERFLOW; +	} +	else +	{ +		/* Get and store instruction to shift in */ +		readVal( &(pXsvfInfo->lvTdi), xsvfGetAsNumBytes( lShiftIrBits ) ); + +		/* Shift the data */ +		iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTIR, +					 lShiftIrBits, &(pXsvfInfo->lvTdi), +					 /*plvTdoCaptured*/0, /*plvTdoExpected*/0, +					 /*plvTdoMask*/0, pXsvfInfo->ucEndIR, +					 pXsvfInfo->lRunTestTime, /*ucMaxRepeat*/0 ); +	} + +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXSDR + * Description:  XSDR <lenVal.TDI[XSDRSIZE]> + *               Shift the given TDI data into the JTAG scan chain. + *               Compare the captured TDO with the expected TDO from the + *               previous XSDRTDO command using the previously specified + *               XTDOMASK. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSDR( SXsvfInfo* pXsvfInfo ) +{ +	int iErrorCode; +	readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes ); +	/* use TDOExpected from last XSDRTDO instruction */ +	iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR, +				 pXsvfInfo->lShiftLengthBits, &(pXsvfInfo->lvTdi), +				 &(pXsvfInfo->lvTdoCaptured), +				 &(pXsvfInfo->lvTdoExpected), +				 &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR, +				 pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat ); +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXRUNTEST + * Description:  XRUNTEST <uint32> + *               Prespecify the XRUNTEST wait time for shift operations. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXRUNTEST( SXsvfInfo* pXsvfInfo ) +{ +	readVal( &(pXsvfInfo->lvTdi), 4 ); +	pXsvfInfo->lRunTestTime = value( &(pXsvfInfo->lvTdi) ); +	XSVFDBG_PRINTF1( 3, "   XRUNTEST = %ld\n", pXsvfInfo->lRunTestTime ); +	return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function:     xsvfDoXREPEAT + * Description:  XREPEAT <byte> + *               Prespecify the maximum number of XC9500/XL retries. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXREPEAT( SXsvfInfo* pXsvfInfo ) +{ +	readByte( &(pXsvfInfo->ucMaxRepeat) ); +	XSVFDBG_PRINTF1( 3, "   XREPEAT = %d\n", +			 ((unsigned int)(pXsvfInfo->ucMaxRepeat)) ); +	return( XSVF_ERROR_NONE ); +} + +/***************************************************************************** + * Function:     xsvfDoXSDRSIZE + * Description:  XSDRSIZE <uint32> + *               Prespecify the XRUNTEST wait time for shift operations. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRSIZE( SXsvfInfo* pXsvfInfo ) +{ +	int iErrorCode; +	iErrorCode  = XSVF_ERROR_NONE; +	readVal( &(pXsvfInfo->lvTdi), 4 ); +	pXsvfInfo->lShiftLengthBits = value( &(pXsvfInfo->lvTdi) ); +	pXsvfInfo->sShiftLengthBytes= xsvfGetAsNumBytes( pXsvfInfo->lShiftLengthBits ); +	XSVFDBG_PRINTF1( 3, "   XSDRSIZE = %ld\n", pXsvfInfo->lShiftLengthBits ); +	if ( pXsvfInfo->sShiftLengthBytes > MAX_LEN ) +	{ +		iErrorCode  = XSVF_ERROR_DATAOVERFLOW; +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXSDRTDO + * Description:  XSDRTDO <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]> + *               Get the TDI and expected TDO values.  Then, shift. + *               Compare the expected TDO with the captured TDO using the + *               prespecified XTDOMASK. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRTDO( SXsvfInfo* pXsvfInfo ) +{ +	int iErrorCode; +	iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), +					pXsvfInfo->lShiftLengthBits, +					pXsvfInfo->sShiftLengthBytes, +					&(pXsvfInfo->lvTdi), +					&(pXsvfInfo->lvTdoCaptured), +					&(pXsvfInfo->lvTdoExpected), +					&(pXsvfInfo->lvTdoMask), +					pXsvfInfo->ucEndDR, +					pXsvfInfo->lRunTestTime, +					pXsvfInfo->ucMaxRepeat ); +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXSETSDRMASKS + * Description:  XSETSDRMASKS <lenVal.AddressMask[XSDRSIZE]> + *                            <lenVal.DataMask[XSDRSIZE]> + *               Get the prespecified address and data mask for the XSDRINC + *               command. + *               Used for xc9500/xl compressed XSVF data. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +#ifdef  XSVF_SUPPORT_COMPRESSION +int xsvfDoXSETSDRMASKS( SXsvfInfo* pXsvfInfo ) +{ +	/* read the addressMask */ +	readVal( &(pXsvfInfo->lvAddressMask), pXsvfInfo->sShiftLengthBytes ); +	/* read the dataMask    */ +	readVal( &(pXsvfInfo->lvDataMask), pXsvfInfo->sShiftLengthBytes ); + +	XSVFDBG_PRINTF( 4, "    Address Mask = " ); +	XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvAddressMask) ); +	XSVFDBG_PRINTF( 4, "\n" ); +	XSVFDBG_PRINTF( 4, "    Data Mask    = " ); +	XSVFDBG_PRINTLENVAL( 4, &(pXsvfInfo->lvDataMask) ); +	XSVFDBG_PRINTF( 4, "\n" ); + +	return( XSVF_ERROR_NONE ); +} +#endif  /* XSVF_SUPPORT_COMPRESSION */ + +/***************************************************************************** + * Function:     xsvfDoXSDRINC + * Description:  XSDRINC <lenVal.firstTDI[XSDRSIZE]> <byte(numTimes)> + *                       <lenVal.data[XSETSDRMASKS.dataMask.len]> ... + *               Get the XSDRINC parameters and execute the XSDRINC command. + *               XSDRINC starts by loading the first TDI shift value. + *               Then, for numTimes, XSDRINC gets the next piece of data, + *               replaces the bits from the starting TDI as defined by the + *               XSETSDRMASKS.dataMask, adds the address mask from + *               XSETSDRMASKS.addressMask, shifts the new TDI value, + *               and compares the TDO to the expected TDO from the previous + *               XSDRTDO command using the XTDOMASK. + *               Used for xc9500/xl compressed XSVF data. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +#ifdef  XSVF_SUPPORT_COMPRESSION +int xsvfDoXSDRINC( SXsvfInfo* pXsvfInfo ) +{ +	int             iErrorCode; +	int             iDataMaskLen; +	unsigned char   ucDataMask; +	unsigned char   ucNumTimes; +	unsigned char   i; + +	readVal( &(pXsvfInfo->lvTdi), pXsvfInfo->sShiftLengthBytes ); +	iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), XTAPSTATE_SHIFTDR, +				 pXsvfInfo->lShiftLengthBits, +				 &(pXsvfInfo->lvTdi), &(pXsvfInfo->lvTdoCaptured), +				 &(pXsvfInfo->lvTdoExpected), +				 &(pXsvfInfo->lvTdoMask), pXsvfInfo->ucEndDR, +				 pXsvfInfo->lRunTestTime, pXsvfInfo->ucMaxRepeat ); +	if ( !iErrorCode ) +	{ +		/* Calculate number of data mask bits */ +		iDataMaskLen    = 0; +		for ( i = 0; i < pXsvfInfo->lvDataMask.len; ++i ) +		{ +			ucDataMask  = pXsvfInfo->lvDataMask.val[ i ]; +			while ( ucDataMask ) +			{ +				iDataMaskLen    += ( ucDataMask & 1 ); +				ucDataMask      >>= 1; +			} +		} + +		/* Get the number of data pieces, i.e. number of times to shift */ +		readByte( &ucNumTimes ); + +		/* For numTimes, get data, fix TDI, and shift */ +		for ( i = 0; !iErrorCode && ( i < ucNumTimes ); ++i ) +		{ +			readVal( &(pXsvfInfo->lvNextData), +				 xsvfGetAsNumBytes( iDataMaskLen ) ); +			xsvfDoSDRMasking( &(pXsvfInfo->lvTdi), +					  &(pXsvfInfo->lvNextData), +					  &(pXsvfInfo->lvAddressMask), +					  &(pXsvfInfo->lvDataMask) ); +			iErrorCode  = xsvfShift( &(pXsvfInfo->ucTapState), +						 XTAPSTATE_SHIFTDR, +						 pXsvfInfo->lShiftLengthBits, +						 &(pXsvfInfo->lvTdi), +						 &(pXsvfInfo->lvTdoCaptured), +						 &(pXsvfInfo->lvTdoExpected), +						 &(pXsvfInfo->lvTdoMask), +						 pXsvfInfo->ucEndDR, +						 pXsvfInfo->lRunTestTime, +						 pXsvfInfo->ucMaxRepeat ); +		} +	} +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} +#endif  /* XSVF_SUPPORT_COMPRESSION */ + +/***************************************************************************** + * Function:     xsvfDoXSDRBCE + * Description:  XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> + *               If not already in SHIFTDR, goto SHIFTDR. + *               Shift the given TDI data into the JTAG scan chain. + *               Ignore TDO. + *               If cmd==XSDRE, then goto ENDDR.  Otherwise, stay in ShiftDR. + *               XSDRB, XSDRC, and XSDRE are the same implementation. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRBCE( SXsvfInfo* pXsvfInfo ) +{ +	unsigned char   ucEndDR; +	int             iErrorCode; +	ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRE ) ? +				  pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR); +	iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), +					pXsvfInfo->lShiftLengthBits, +					pXsvfInfo->sShiftLengthBytes, +					&(pXsvfInfo->lvTdi), +					/*plvTdoCaptured*/0, /*plvTdoExpected*/0, +					/*plvTdoMask*/0, ucEndDR, +					/*lRunTestTime*/0, /*ucMaxRepeat*/0 ); +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXSDRTDOBCE + * Description:  XSDRB/XSDRC/XSDRE <lenVal.TDI[XSDRSIZE]> <lenVal.TDO[XSDRSIZE]> + *               If not already in SHIFTDR, goto SHIFTDR. + *               Shift the given TDI data into the JTAG scan chain. + *               Compare TDO, but do NOT use XTDOMASK. + *               If cmd==XSDRTDOE, then goto ENDDR.  Otherwise, stay in ShiftDR. + *               XSDRTDOB, XSDRTDOC, and XSDRTDOE are the same implementation. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSDRTDOBCE( SXsvfInfo* pXsvfInfo ) +{ +	unsigned char   ucEndDR; +	int             iErrorCode; +	ucEndDR = (unsigned char)(( pXsvfInfo->ucCommand == XSDRTDOE ) ? +				  pXsvfInfo->ucEndDR : XTAPSTATE_SHIFTDR); +	iErrorCode  = xsvfBasicXSDRTDO( &(pXsvfInfo->ucTapState), +					pXsvfInfo->lShiftLengthBits, +					pXsvfInfo->sShiftLengthBytes, +					&(pXsvfInfo->lvTdi), +					&(pXsvfInfo->lvTdoCaptured), +					&(pXsvfInfo->lvTdoExpected), +					/*plvTdoMask*/0, ucEndDR, +					/*lRunTestTime*/0, /*ucMaxRepeat*/0 ); +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXSTATE + * Description:  XSTATE <byte> + *               <byte> == XTAPSTATE; + *               Get the state parameter and transition the TAP to that state. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXSTATE( SXsvfInfo* pXsvfInfo ) +{ +	unsigned char   ucNextState; +	int             iErrorCode; +	readByte( &ucNextState ); +	iErrorCode  = xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucNextState ); +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXENDXR + * Description:  XENDIR/XENDDR <byte> + *               <byte>:  0 = RUNTEST;  1 = PAUSE. + *               Get the prespecified XENDIR or XENDDR. + *               Both XENDIR and XENDDR use the same implementation. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXENDXR( SXsvfInfo* pXsvfInfo ) +{ +	int             iErrorCode; +	unsigned char   ucEndState; + +	iErrorCode  = XSVF_ERROR_NONE; +	readByte( &ucEndState ); +	if ( ( ucEndState != XENDXR_RUNTEST ) && ( ucEndState != XENDXR_PAUSE ) ) +	{ +		iErrorCode  = XSVF_ERROR_ILLEGALSTATE; +	} +	else +	{ + +		if ( pXsvfInfo->ucCommand == XENDIR ) +		{ +			if ( ucEndState == XENDXR_RUNTEST ) +			{ +				pXsvfInfo->ucEndIR  = XTAPSTATE_RUNTEST; +			} +			else +			{ +				pXsvfInfo->ucEndIR  = XTAPSTATE_PAUSEIR; +			} +			XSVFDBG_PRINTF1( 3, "   ENDIR State = %s\n", +					 xsvf_pzTapState[ pXsvfInfo->ucEndIR ] ); +		} +		else    /* XENDDR */ +		{ +			if ( ucEndState == XENDXR_RUNTEST ) +			{ +				pXsvfInfo->ucEndDR  = XTAPSTATE_RUNTEST; +			} +			else +			{ +				pXsvfInfo->ucEndDR  = XTAPSTATE_PAUSEDR; +			} +			XSVFDBG_PRINTF1( 3, "   ENDDR State = %s\n", +					 xsvf_pzTapState[ pXsvfInfo->ucEndDR ] ); +		} +	} + +	if ( iErrorCode != XSVF_ERROR_NONE ) +	{ +		pXsvfInfo->iErrorCode   = iErrorCode; +	} +	return( iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXCOMMENT + * Description:  XCOMMENT <text string ending in \0> + *               <text string ending in \0> == text comment; + *               Arbitrary comment embedded in the XSVF. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXCOMMENT( SXsvfInfo* pXsvfInfo ) +{ +	/* Use the comment for debugging */ +	/* Otherwise, read through the comment to the end '\0' and ignore */ +	unsigned char   ucText; + +	if ( xsvf_iDebugLevel > 0 ) +	{ +		putc( ' ' ); +	} + +	do +	{ +		readByte( &ucText ); +		if ( xsvf_iDebugLevel > 0 ) +		{ +			putc( ucText ? ucText : '\n' ); +		} +	} while ( ucText ); + +	pXsvfInfo->iErrorCode   = XSVF_ERROR_NONE; + +	return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfDoXWAIT + * Description:  XWAIT <wait_state> <end_state> <wait_time> + *               If not already in <wait_state>, then go to <wait_state>. + *               Wait in <wait_state> for <wait_time> microseconds. + *               Finally, if not already in <end_state>, then goto <end_state>. + * Parameters:   pXsvfInfo   - XSVF information pointer. + * Returns:      int         - 0 = success;  non-zero = error. + *****************************************************************************/ +int xsvfDoXWAIT( SXsvfInfo* pXsvfInfo ) +{ +	unsigned char   ucWaitState; +	unsigned char   ucEndState; +	long            lWaitTime; + +	/* Get Parameters */ +	/* <wait_state> */ +	readVal( &(pXsvfInfo->lvTdi), 1 ); +	ucWaitState = pXsvfInfo->lvTdi.val[0]; + +	/* <end_state> */ +	readVal( &(pXsvfInfo->lvTdi), 1 ); +	ucEndState = pXsvfInfo->lvTdi.val[0]; + +	/* <wait_time> */ +	readVal( &(pXsvfInfo->lvTdi), 4 ); +	lWaitTime = value( &(pXsvfInfo->lvTdi) ); +	XSVFDBG_PRINTF2( 3, "   XWAIT:  state = %s; time = %ld\n", +			 xsvf_pzTapState[ ucWaitState ], lWaitTime ); + +	/* If not already in <wait_state>, go to <wait_state> */ +	if ( pXsvfInfo->ucTapState != ucWaitState ) +	{ +		xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucWaitState ); +	} + +	/* Wait for <wait_time> microseconds */ +	waitTime( lWaitTime ); + +	/* If not already in <end_state>, go to <end_state> */ +	if ( pXsvfInfo->ucTapState != ucEndState ) +	{ +		xsvfGotoTapState( &(pXsvfInfo->ucTapState), ucEndState ); +	} + +	return( XSVF_ERROR_NONE ); +} + + +/*============================================================================ + * Execution Control Functions + ============================================================================*/ + +/***************************************************************************** + * Function:     xsvfInitialize + * Description:  Initialize the xsvf player. + *               Call this before running the player to initialize the data + *               in the SXsvfInfo struct. + *               xsvfCleanup is called to clean up the data in SXsvfInfo + *               after the XSVF is played. + * Parameters:   pXsvfInfo   - ptr to the XSVF information. + * Returns:      int - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfInitialize( SXsvfInfo* pXsvfInfo ) +{ +	/* Initialize values */ +	pXsvfInfo->iErrorCode   = xsvfInfoInit( pXsvfInfo ); + +	if ( !pXsvfInfo->iErrorCode ) +	{ +		/* Initialize the TAPs */ +		pXsvfInfo->iErrorCode   = xsvfGotoTapState( &(pXsvfInfo->ucTapState), +							    XTAPSTATE_RESET ); +	} + +	return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfRun + * Description:  Run the xsvf player for a single command and return. + *               First, call xsvfInitialize. + *               Then, repeatedly call this function until an error is detected + *               or until the pXsvfInfo->ucComplete variable is non-zero. + *               Finally, call xsvfCleanup to cleanup any remnants. + * Parameters:   pXsvfInfo   - ptr to the XSVF information. + * Returns:      int         - 0 = success; otherwise error. + *****************************************************************************/ +int xsvfRun( SXsvfInfo* pXsvfInfo ) +{ +	/* Process the XSVF commands */ +	if ( (!pXsvfInfo->iErrorCode) && (!pXsvfInfo->ucComplete) ) +	{ +		/* read 1 byte for the instruction */ +		readByte( &(pXsvfInfo->ucCommand) ); +		++(pXsvfInfo->lCommandCount); + +		if ( pXsvfInfo->ucCommand < XLASTCMD ) +		{ +			/* Execute the command.  Func sets error code. */ +			XSVFDBG_PRINTF1( 2, "  %s\n", +					 xsvf_pzCommandName[pXsvfInfo->ucCommand] ); +			/* If your compiler cannot take this form, +			   then convert to a switch statement */ +#if 0 /* test-only */ +			xsvf_pfDoCmd[ pXsvfInfo->ucCommand ]( pXsvfInfo ); +#else +			switch (pXsvfInfo->ucCommand) { +			case 0: +				xsvfDoXCOMPLETE(pXsvfInfo);        /*  0 */ +				break; +			case 1: +				xsvfDoXTDOMASK(pXsvfInfo);         /*  1 */ +				break; +			case 2: +				xsvfDoXSIR(pXsvfInfo);             /*  2 */ +				break; +			case 3: +				xsvfDoXSDR(pXsvfInfo);             /*  3 */ +				break; +			case 4: +				xsvfDoXRUNTEST(pXsvfInfo);         /*  4 */ +				break; +			case 5: +				xsvfDoIllegalCmd(pXsvfInfo);       /*  5 */ +				break; +			case 6: +				xsvfDoIllegalCmd(pXsvfInfo);       /*  6 */ +				break; +			case 7: +				xsvfDoXREPEAT(pXsvfInfo);          /*  7 */ +				break; +			case 8: +				xsvfDoXSDRSIZE(pXsvfInfo);         /*  8 */ +				break; +			case 9: +				xsvfDoXSDRTDO(pXsvfInfo);          /*  9 */ +				break; +#ifdef  XSVF_SUPPORT_COMPRESSION +			case 10: +				xsvfDoXSETSDRMASKS(pXsvfInfo);     /* 10 */ +				break; +			case 11: +				xsvfDoXSDRINC(pXsvfInfo);          /* 11 */ +				break; +#else +			case 10: +				xsvfDoIllegalCmd(pXsvfInfo);       /* 10 */ +				break; +			case 11: +				xsvfDoIllegalCmd(pXsvfInfo);       /* 11 */ +				break; +#endif  /* XSVF_SUPPORT_COMPRESSION */ +			case 12: +				xsvfDoXSDRBCE(pXsvfInfo);          /* 12 */ +				break; +			case 13: +				xsvfDoXSDRBCE(pXsvfInfo);          /* 13 */ +				break; +			case 14: +				xsvfDoXSDRBCE(pXsvfInfo);          /* 14 */ +				break; +			case 15: +				xsvfDoXSDRTDOBCE(pXsvfInfo);       /* 15 */ +				break; +			case 16: +				xsvfDoXSDRTDOBCE(pXsvfInfo);       /* 16 */ +				break; +			case 17: +				xsvfDoXSDRTDOBCE(pXsvfInfo);       /* 17 */ +				break; +			case 18: +				xsvfDoXSTATE(pXsvfInfo);           /* 18 */ +				break; +			case 19: +				xsvfDoXENDXR(pXsvfInfo);           /* 19 */ +				break; +			case 20: +				xsvfDoXENDXR(pXsvfInfo);           /* 20 */ +				break; +			case 21: +				xsvfDoXSIR2(pXsvfInfo);            /* 21 */ +				break; +			case 22: +				xsvfDoXCOMMENT(pXsvfInfo);         /* 22 */ +				break; +			case 23: +				xsvfDoXWAIT(pXsvfInfo);             /* 23 */ +				break; +			} +#endif +		} +		else +		{ +			/* Illegal command value.  Func sets error code. */ +			xsvfDoIllegalCmd( pXsvfInfo ); +		} +	} + +	return( pXsvfInfo->iErrorCode ); +} + +/***************************************************************************** + * Function:     xsvfCleanup + * Description:  cleanup remnants of the xsvf player. + * Parameters:   pXsvfInfo   - ptr to the XSVF information. + * Returns:      void. + *****************************************************************************/ +void xsvfCleanup( SXsvfInfo* pXsvfInfo ) +{ +	xsvfInfoCleanup( pXsvfInfo ); +} + + +/*============================================================================ + * xsvfExecute() - The primary entry point to the XSVF player + ============================================================================*/ + +/***************************************************************************** + * Function:     xsvfExecute + * Description:  Process, interpret, and apply the XSVF commands. + *               See port.c:readByte for source of XSVF data. + * Parameters:   none. + * Returns:      int - Legacy result values:  1 == success;  0 == failed. + *****************************************************************************/ +int xsvfExecute(void) +{ +	SXsvfInfo   xsvfInfo; + +	xsvfInitialize( &xsvfInfo ); + +	while ( !xsvfInfo.iErrorCode && (!xsvfInfo.ucComplete) ) +	{ +		xsvfRun( &xsvfInfo ); +	} + +	if ( xsvfInfo.iErrorCode ) +	{ +		XSVFDBG_PRINTF1( 0, "%s\n", xsvf_pzErrorName[ +					 ( xsvfInfo.iErrorCode < XSVF_ERROR_LAST ) +					 ? xsvfInfo.iErrorCode : XSVF_ERROR_UNKNOWN ] ); +		XSVFDBG_PRINTF2( 0, "ERROR at or near XSVF command #%ld.  See line #%ld in the XSVF ASCII file.\n", +				 xsvfInfo.lCommandCount, xsvfInfo.lCommandCount ); +	} +	else +	{ +		XSVFDBG_PRINTF( 0, "SUCCESS - Completed XSVF execution.\n" ); +	} + +	xsvfCleanup( &xsvfInfo ); + +	return( XSVF_ERRORCODE(xsvfInfo.iErrorCode) ); +} + + +/***************************************************************************** + * Function:     do_cpld + * Description:  main function. + *               Specified here for creating stand-alone debug executable. + *               Embedded users should call xsvfExecute() directly. + * Parameters:   iArgc    - number of command-line arguments. + *               ppzArgv  - array of ptrs to strings (command-line arguments). + * Returns:      int      - Legacy return value:  1 = success; 0 = error. + *****************************************************************************/ +int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	int     iErrorCode; +	unsigned long duration; +	unsigned long long startClock, endClock; + +	if (argc == 2) +		xsvfdata = (unsigned char *)simple_strtoul(argv[1], NULL, 16); +	else { +#ifdef CONFIG_SYS_XSVF_DEFAULT_ADDR +		xsvfdata = (unsigned char *)CONFIG_SYS_XSVF_DEFAULT_ADDR; +#else +		printf("Usage:\ncpld %s\n", cmdtp->help); +		return -1; +#endif +	} + +	iErrorCode          = XSVF_ERRORCODE( XSVF_ERROR_NONE ); +	xsvf_iDebugLevel    = 0; + +	printf("XSVF Player v%s, Xilinx, Inc.\n", XSVF_VERSION); +	printf("Reading XSVF data @ %p\n", xsvfdata); + +	/* Initialize the I/O.  SetPort initializes I/O on first call */ +	setPort( TMS, 1 ); + +	/* Execute the XSVF in the file */ +	startClock  = get_ticks(); +	iErrorCode  = xsvfExecute(); +	endClock    = get_ticks(); +	duration    = (unsigned long)(endClock - startClock); +	printf("\nExecution Time = %d seconds\n", (int)(duration/get_tbclk())); + +	return( iErrorCode ); +} +U_BOOT_CMD( +	cpld,	2,	1,	do_cpld, +	"program onboard CPLD", +	"<xsvf-addr>" +); diff --git a/roms/u-boot/board/esd/common/xilinx_jtag/micro.h b/roms/u-boot/board/esd/common/xilinx_jtag/micro.h new file mode 100644 index 00000000..e9a76128 --- /dev/null +++ b/roms/u-boot/board/esd/common/xilinx_jtag/micro.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/***************************************************************************** + * File:         micro.h + * Description:  This header file contains the function prototype to the + *               primary interface function for the XSVF player. + * Usage:        FIRST - PORTS.C + *               Customize the ports.c function implementations to establish + *               the correct protocol for communicating with your JTAG ports + *               (setPort() and readTDOBit()) and tune the waitTime() delay + *               function.  Also, establish access to the XSVF data source + *               in the readByte() function. + *               FINALLY - Call xsvfExecute(). + *****************************************************************************/ +#ifndef XSVF_MICRO_H +#define XSVF_MICRO_H + +/* Legacy error codes for xsvfExecute from original XSVF player v2.0 */ +#define XSVF_LEGACY_SUCCESS 1 +#define XSVF_LEGACY_ERROR   0 + +/* 4.04 [NEW] Error codes for xsvfExecute. */ +/* Must #define XSVF_SUPPORT_ERRORCODES in micro.c to get these codes */ +#define XSVF_ERROR_NONE         0 +#define XSVF_ERROR_UNKNOWN      1 +#define XSVF_ERROR_TDOMISMATCH  2 +#define XSVF_ERROR_MAXRETRIES   3   /* TDO mismatch after max retries */ +#define XSVF_ERROR_ILLEGALCMD   4 +#define XSVF_ERROR_ILLEGALSTATE 5 +#define XSVF_ERROR_DATAOVERFLOW 6   /* Data > lenVal MAX_LEN buffer size*/ +/* Insert new errors here */ +#define XSVF_ERROR_LAST         7 + +/***************************************************************************** + * Function:     xsvfExecute + * Description:  Process, interpret, and apply the XSVF commands. + *               See port.c:readByte for source of XSVF data. + * Parameters:   none. + * Returns:      int - For error codes see above. + *****************************************************************************/ +int xsvfExecute(void); + +#endif  /* XSVF_MICRO_H */ diff --git a/roms/u-boot/board/esd/common/xilinx_jtag/ports.c b/roms/u-boot/board/esd/common/xilinx_jtag/ports.c new file mode 100644 index 00000000..d79dbd1e --- /dev/null +++ b/roms/u-boot/board/esd/common/xilinx_jtag/ports.c @@ -0,0 +1,99 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/*******************************************************/ +/* file: ports.c                                       */ +/* abstract:  This file contains the routines to       */ +/*            output values on the JTAG ports, to read */ +/*            the TDO bit, and to read a byte of data  */ +/*            from the prom                            */ +/*                                                     */ +/*******************************************************/ + +#include <common.h> +#include <asm/processor.h> +#include <asm/io.h> + +#include "ports.h" + +static unsigned long output = 0; +static int filepos = 0; +static int oldstate = 0; +static int newstate = 0; +static int readptr = 0; + +extern const unsigned char *xsvfdata; + +/* if in debugging mode, then just set the variables */ +void setPort(short p,short val) +{ +	if (p==TMS) { +		if (val) { +			output |= JTAG_TMS; +		} else { +			output &= ~JTAG_TMS; +		} +	} +	if (p==TDI) { +		if (val) { +			output |= JTAG_TDI; +		} else { +			output &= ~JTAG_TDI; +		} +	} +	if (p==TCK) { +		if (val) { +			output |= JTAG_TCK; +		} else { +			output &= ~JTAG_TCK; +		} +		out_be32((void *)GPIO0_OR, output); +	} +} + + +/* toggle tck LH */ +void pulseClock(void) +{ +	setPort(TCK,0);  /* set the TCK port to low  */ +	setPort(TCK,1);  /* set the TCK port to high */ +} + + +/* read in a byte of data from the prom */ +void readByte(unsigned char *data) +{ +	/* pretend reading using a file */ +	*data = xsvfdata[readptr++]; +	newstate = filepos++ >> 10; +	if (newstate != oldstate) { +		printf("%4d kB\r\r\r\r", newstate); +		oldstate = newstate; +	} +} + +/* read the TDO bit from port */ +unsigned char readTDOBit(void) +{ +	unsigned long inputs; + +	inputs = in_be32((void *)GPIO0_IR); +	if (inputs & JTAG_TDO) +		return 1; +	else +		return 0; +} + + +/* Wait at least the specified number of microsec.                           */ +/* Use a timer if possible; otherwise estimate the number of instructions    */ +/* necessary to be run based on the microcontroller speed.  For this example */ +/* we pulse the TCK port a number of times based on the processor speed.     */ +void waitTime(long microsec) +{ +	udelay(microsec); /* esd */ +} diff --git a/roms/u-boot/board/esd/common/xilinx_jtag/ports.h b/roms/u-boot/board/esd/common/xilinx_jtag/ports.h new file mode 100644 index 00000000..8ee7de92 --- /dev/null +++ b/roms/u-boot/board/esd/common/xilinx_jtag/ports.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2003 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/*******************************************************/ +/* file: ports.h                                       */ +/* abstract:  This file contains extern declarations   */ +/*            for providing stimulus to the JTAG ports.*/ +/*******************************************************/ + +#ifndef ports_dot_h +#define ports_dot_h + +/* these constants are used to send the appropriate ports to setPort */ +/* they should be enumerated types, but some of the microcontroller  */ +/* compilers don't like enumerated types */ +#define TCK (short) 0 +#define TMS (short) 1 +#define TDI (short) 2 + +/* + * Use CONFIG_SYS_FPGA_xxx defines from board include file. + */ +#define JTAG_TMS   CONFIG_SYS_FPGA_PRG     /* output */ +#define JTAG_TCK   CONFIG_SYS_FPGA_CLK     /* output */ +#define JTAG_TDI   CONFIG_SYS_FPGA_DATA    /* output */ +#define JTAG_TDO   CONFIG_SYS_FPGA_DONE    /* input */ + +/* set the port "p" (TCK, TMS, or TDI) to val (0 or 1) */ +void setPort(short p, short val); + +/* read the TDO bit and store it in val */ +unsigned char readTDOBit(void); + +/* make clock go down->up->down*/ +void pulseClock(void); + +/* read the next byte of data from the xsvf file */ +void readByte(unsigned char *data); + +void waitTime(long microsec); + +#endif  | 
