diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/u-boot/board/hermes | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/board/hermes')
| -rw-r--r-- | roms/u-boot/board/hermes/Makefile | 8 | ||||
| -rw-r--r-- | roms/u-boot/board/hermes/flash.c | 444 | ||||
| -rw-r--r-- | roms/u-boot/board/hermes/hermes.c | 590 | ||||
| -rw-r--r-- | roms/u-boot/board/hermes/u-boot.lds | 88 | ||||
| -rw-r--r-- | roms/u-boot/board/hermes/u-boot.lds.debug | 121 | 
5 files changed, 1251 insertions, 0 deletions
diff --git a/roms/u-boot/board/hermes/Makefile b/roms/u-boot/board/hermes/Makefile new file mode 100644 index 00000000..ccca520e --- /dev/null +++ b/roms/u-boot/board/hermes/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2000-2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	= hermes.o flash.o diff --git a/roms/u-boot/board/hermes/flash.c b/roms/u-boot/board/hermes/flash.c new file mode 100644 index 00000000..38d3cd39 --- /dev/null +++ b/roms/u-boot/board/hermes/flash.c @@ -0,0 +1,444 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <mpc8xx.h> + +flash_info_t	flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips	*/ + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size (vu_long *addr, flash_info_t *info); +static int write_byte (flash_info_t *info, ulong dest, uchar data); +static void flash_get_offsets (ulong base, flash_info_t *info); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ +	volatile immap_t     *immap  = (immap_t *)CONFIG_SYS_IMMR; +	volatile memctl8xx_t *memctl = &immap->im_memctl; +	unsigned long size; +	int i; + +	/* Init: no FLASHes known */ +	for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) { +		flash_info[i].flash_id = FLASH_UNKNOWN; +	} + +	/* Static FLASH Bank configuration here - FIXME XXX */ + +	size = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]); + +	if (flash_info[0].flash_id == FLASH_UNKNOWN) { +		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", +			size, size<<20); +	} + +	/* Remap FLASH according to real size */ +	memctl->memc_or0 = CONFIG_SYS_OR_TIMING_FLASH | (-size & 0xFFFF8000); +	memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | +				(memctl->memc_br0 & ~(BR_BA_MSK)); + +	/* Re-do sizing to get full correct info */ +	size = flash_get_size((vu_long *)CONFIG_SYS_FLASH_BASE, &flash_info[0]); + +	flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]); + +#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE +	/* monitor protection ON by default */ +	flash_protect(FLAG_PROTECT_SET, +		      CONFIG_SYS_MONITOR_BASE, +		      CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1, +		      &flash_info[0]); +#endif + +	flash_info[0].size = size; + +	return (size); +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t *info) +{ +	int i; + +	/* set up sector start address table */ +	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; + +	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; +	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_AM320B:	printf ("AM29LV320B (32 Mbit, bottom boot sect)\n"); +				break; +	case FLASH_AM320T:	printf ("AM29LV320T (32 Mbit, top boot sector)\n"); +				break; +	default:		printf ("Unknown Chip Type\n"); +				break; +	} + +	printf ("  Size: %ld MB in %d Sectors\n", +		info->size >> 20, info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i=0; i<info->sector_count; ++i) { +		if ((i % 5) == 0) +			printf ("\n   "); +		printf (" %08lX%s", +			info->start[i], +			info->protect[i] ? " (RO)" : "     " +		); +	} +	printf ("\n"); +	return; +} + +/*----------------------------------------------------------------------- + */ + + +/*----------------------------------------------------------------------- + */ + +/* + * The following code cannot be run from FLASH! + */ + +static ulong flash_get_size (vu_long *addr, flash_info_t *info) +{ +	short i; +	uchar value; +	vu_char *caddr = (vu_char *)addr; +	ulong base = (ulong)addr; + + +	/* Write auto select command: read Manufacturer ID */ +	caddr[0x0AAA] = 0xAA; +	caddr[0x0555] = 0x55; +	caddr[0x0AAA] = 0x90; + +	value = caddr[0]; +	switch (value) { +	case (AMD_MANUFACT & 0xFF): +		info->flash_id = FLASH_MAN_AMD; +		break; +	case (FUJ_MANUFACT & 0xFF): +		info->flash_id = FLASH_MAN_FUJ; +		break; +	default: +		info->flash_id = FLASH_UNKNOWN; +		info->sector_count = 0; +		info->size = 0; +		return (0);			/* no or unknown flash	*/ +	} + +	value = caddr[2];			/* device ID		*/ + +	switch (value) { +	case (AMD_ID_LV400T & 0xFF): +		info->flash_id += FLASH_AM400T; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;				/* => 512 kB		*/ + +	case (AMD_ID_LV400B & 0xFF): +		info->flash_id += FLASH_AM400B; +		info->sector_count = 11; +		info->size = 0x00080000; +		break;				/* => 512 kB		*/ + +	case (AMD_ID_LV800T & 0xFF): +		info->flash_id += FLASH_AM800T; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;				/* => 1 MB		*/ + +	case (AMD_ID_LV800B & 0xFF): +		info->flash_id += FLASH_AM800B; +		info->sector_count = 19; +		info->size = 0x00100000; +		break;				/* => 1 MB		*/ + +	case (AMD_ID_LV160T & 0xFF): +		info->flash_id += FLASH_AM160T; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;				/* => 2 MB		*/ + +	case (AMD_ID_LV160B & 0xFF): +		info->flash_id += FLASH_AM160B; +		info->sector_count = 35; +		info->size = 0x00200000; +		break;				/* => 2 MB		*/ +#if 0	/* enable when device IDs are available */ +	case (AMD_ID_LV320T & 0xFF): +		info->flash_id += FLASH_AM320T; +		info->sector_count = 67; +		info->size = 0x00400000; +		break;				/* => 4 MB		*/ + +	case (AMD_ID_LV320B & 0xFF): +		info->flash_id += FLASH_AM320B; +		info->sector_count = 67; +		info->size = 0x00400000; +		break;				/* => 4 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_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: D0 = 1 if protected */ +		caddr = (volatile unsigned char *)(info->start[i]); +		info->protect[i] = caddr[4] & 1; +	} + +	/* +	 * Prevent writes to uninitialized FLASH. +	 */ +	if (info->flash_id != FLASH_UNKNOWN) { +		caddr = (vu_char *)info->start[0]; + +		*caddr = 0xF0;	/* reset bank */ +	} + +	return (info->size); +} + + +/*----------------------------------------------------------------------- + */ + +int	flash_erase (flash_info_t *info, int s_first, int s_last) +{ +	vu_char *addr = (vu_char*)(info->start[0]); +	int flag, prot, sect, l_sect; +	ulong start, now, last; + +	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) || +	    (info->flash_id > FLASH_AMD_COMP)) { +		printf ("Can't erase unknown flash type %08lx - aborted\n", +			info->flash_id); +		return 1; +	} + +	prot = 0; +	for (sect=s_first; sect<=s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		} +	} + +	if (prot) { +		printf ("- Warning: %d protected sectors will not be erased!\n", +			prot); +	} else { +		printf ("\n"); +	} + +	l_sect = -1; + +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts(); + +	addr[0x0AAA] = 0xAA; +	addr[0x0555] = 0x55; +	addr[0x0AAA] = 0x80; +	addr[0x0AAA] = 0xAA; +	addr[0x0555] = 0x55; + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect<=s_last; sect++) { +		if (info->protect[sect] == 0) {	/* not protected */ +			addr = (vu_char*)(info->start[sect]); +			addr[0] = 0x30; +			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 = (vu_char*)(info->start[l_sect]); +	while ((addr[0] & 0x80) != 0x80) { +		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 = (vu_char *)info->start[0]; +	addr[0] = 0xF0;	/* 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) +{ +	int rc; + +	while (cnt > 0) { +		if ((rc = write_byte(info, addr++, *src++)) != 0) { +			return (rc); +		} +		--cnt; +	} + +	return (0); +} + +/*----------------------------------------------------------------------- + * Write a word to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_byte (flash_info_t *info, ulong dest, uchar data) +{ +	vu_char *addr = (vu_char*)(info->start[0]); +	ulong start; +	int flag; + +	/* Check if Flash is (sufficiently) erased */ +	if ((*((vu_char *)dest) & data) != data) { +		return (2); +	} +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts(); + +	addr[0x0AAA] = 0xAA; +	addr[0x0555] = 0x55; +	addr[0x0AAA] = 0xA0; + +	*((vu_char *)dest) = data; + +	/* re-enable interrupts if necessary */ +	if (flag) +		enable_interrupts(); + +	/* data polling for D7 */ +	start = get_timer (0); +	while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) { +		if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { +			return (1); +		} +	} +	return (0); +} + +/*----------------------------------------------------------------------- + */ diff --git a/roms/u-boot/board/hermes/hermes.c b/roms/u-boot/board/hermes/hermes.c new file mode 100644 index 00000000..6126b734 --- /dev/null +++ b/roms/u-boot/board/hermes/hermes.c @@ -0,0 +1,590 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <commproc.h> +#include <mpc8xx.h> + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +# include <status_led.h> +# define SHOW_BOOT_PROGRESS(arg)	bootstage_mark(arg) +#else +# define SHOW_BOOT_PROGRESS(arg) +#endif + +DECLARE_GLOBAL_DATA_PTR; + +/* ------------------------------------------------------------------------- */ + +static long int dram_size (long int, long int *, long int); +static ulong board_init (void); +static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd, +							uchar * msg); + +/* ------------------------------------------------------------------------- */ + +#define	_NOT_USED_	0xFFFFFFFF + +const uint sdram_table[] = { +	/* +	 * Single Read. (Offset 0 in UPMA RAM) +	 */ +	0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00, +	0x1ff77c47,					/* last */ +	/* +	 * SDRAM Initialization (offset 5 in UPMA RAM) +	 * +	 * This is no UPM entry point. The following definition uses +	 * the remaining space to establish an initialization +	 * sequence, which is executed by a RUN command. +	 * +	 */ +	0x1fe77c35, 0xffaffc34, 0x1fa57c35,	/* last */ +	/* +	 * Burst Read. (Offset 8 in UPMA RAM) +	 */ +	0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00, +	0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,	/* last */ +	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, +	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, +	/* +	 * Single Write. (Offset 18 in UPMA RAM) +	 */ +	0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,	/* last */ +	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, +	/* +	 * Burst Write. (Offset 20 in UPMA RAM) +	 */ +	0x1f07fc04, 0xeeaebc00, 0x10ad4c00, 0xf0afcc00, +	0xf0afcc00, 0xe1bb8c06, 0x1ff77c47,	/* last */ +	_NOT_USED_, +	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, +	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, +	/* +	 * Refresh  (Offset 30 in UPMA RAM) +	 */ +	0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04, +	0xfffffc84, 0xfffffc07,		/* last */ +	_NOT_USED_, _NOT_USED_, +	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, +	/* +	 * Exception. (Offset 3c in UPMA RAM) +	 */ +	0x7ffffc07,					/* last */ +	_NOT_USED_, _NOT_USED_, _NOT_USED_, +}; + +/* ------------------------------------------------------------------------- */ + + +/* + * Check Board Identity: + * + * Test ID string (HERMES...) + * + * Return code for board revision and network speed + */ + +int checkboard (void) +{ +	char buf[64]; +	int i; +	int l = getenv_f("serial#", buf, sizeof(buf)); + +	puts ("Board: "); + +	if (l < 0 || strncmp(buf, "HERMES", 6)) { +		puts ("### No HW ID - assuming HERMES-PRO"); +	} else { +		for (i = 0; i < l; i++) { +			if (buf[i] == ' ') +				break; +			putc (buf[i]); +		} +	} + +	gd->board_type = board_init (); + +	printf ("  Rev. %ld.x\n", (gd->board_type >> 16)); + +	return (0); +} + +/* ------------------------------------------------------------------------- */ + +phys_size_t initdram (int board_type) +{ +	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +	volatile memctl8xx_t *memctl = &immap->im_memctl; +	long int size, size8, size9; + +	upmconfig (UPMA, (uint *) sdram_table, +			   sizeof (sdram_table) / sizeof (uint)); + +	/* +	 * Preliminary prescaler for refresh +	 */ +	memctl->memc_mptpr = 0x0400; + +	memctl->memc_mar = 0x00000088; + +	/* +	 * Map controller banks 1 to the SDRAM banks at preliminary address +	 */ +	memctl->memc_or1 = CONFIG_SYS_OR1_PRELIM; +	memctl->memc_br1 = CONFIG_SYS_BR1_PRELIM; + +	/* HERMES-PRO boards have only one bank SDRAM */ + + +	udelay (200); + +	/* perform SDRAM initializsation sequence */ + +	memctl->memc_mamr = 0xD0802114; +	memctl->memc_mcr = 0x80002105; +	udelay (1); +	memctl->memc_mamr = 0xD0802118; +	memctl->memc_mcr = 0x80002130; +	udelay (1); +	memctl->memc_mamr = 0xD0802114; +	memctl->memc_mcr = 0x80002106; + +	udelay (1000); + +	/* +	 * Check Bank 0 Memory Size for re-configuration +	 * +	 * try 8 column mode +	 */ +	size8 = dram_size (CONFIG_SYS_MAMR_8COL, (long *) SDRAM_BASE_PRELIM, +					   SDRAM_MAX_SIZE); + +	udelay (1000); + +	/* +	 * try 9 column mode +	 */ +	size9 = dram_size (CONFIG_SYS_MAMR_9COL, (long *) SDRAM_BASE_PRELIM, +					   SDRAM_MAX_SIZE); + +	if (size8 < size9) {		/* leave configuration at 9 columns */ +		size = size9; +/*	debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20);	*/ +	} else {					/* back to 8 columns            */ +		size = size8; +		memctl->memc_mamr = CONFIG_SYS_MAMR_8COL; +		udelay (500); +/*	debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20);	*/ +	} + +	udelay (1000); + +	memctl->memc_or1 = ((-size) & 0xFFFF0000) | SDRAM_TIMING; +	memctl->memc_br1 = (CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V; + +	udelay (10000); + +	return (size); +} + +/* ------------------------------------------------------------------------- */ + +/* + * Check memory range for valid RAM. A simple memory test determines + * the actually available RAM size between addresses `base' and + * `base + maxsize'. Some (not all) hardware errors are detected: + * - short between address lines + * - short between data lines + */ + +static long int dram_size (long int mamr_value, long int *base, +						   long int maxsize) +{ +	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; +	volatile memctl8xx_t *memctl = &immap->im_memctl; + +	memctl->memc_mamr = mamr_value; + +	return (get_ram_size(base, maxsize)); +} + +/* ------------------------------------------------------------------------- */ + +#define	PB_LED_3	0x00020000	/* Status LED's */ +#define PB_LED_2	0x00010000 +#define PB_LED_1	0x00008000 +#define PB_LED_0	0x00004000 + +#define PB_LED_ALL	(PB_LED_0 | PB_LED_1 | PB_LED_2 | PB_LED_3) + +#define	PC_REP_SPD1	0x00000800 +#define PC_REP_SPD0	0x00000400 + +#define PB_RESET_2081	0x00000020	/* Reset PEB2081 */ + +#define PB_MAI_4	0x00000010	/* Configuration */ +#define PB_MAI_3	0x00000008 +#define PB_MAI_2	0x00000004 +#define PB_MAI_1	0x00000002 +#define PB_MAI_0	0x00000001 + +#define PB_MAI_ALL	(PB_MAI_0 | PB_MAI_1 | PB_MAI_2 | PB_MAI_3 | PB_MAI_4) + + +#define	PC_REP_MGRPRS	0x0200 +#define PC_REP_SPD	0x0040		/* Select 100 Mbps */ +#define PC_REP_RES	0x0004 +#define PC_BIT14	0x0002		/* ??? */ +#define PC_BIT15	0x0001		/* ??? ENDSL ?? */ + +/* ------------------------------------------------------------------------- */ + +static ulong board_init (void) +{ +	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; +	ulong reg, revision, speed = 100; +	int ethspeed; +	char *s; + +	if ((s = getenv ("ethspeed")) != NULL) { +		if (strcmp (s, "100") == 0) { +			ethspeed = 100; +		} else if (strcmp (s, "10") == 0) { +			ethspeed = 10; +		} else { +			ethspeed = 0; +		} +	} else { +		ethspeed = 0; +	} + +	/* Configure Port B Output Pins => 0x0003cc3F */ +	reg = PB_LED_ALL | PC_REP_SPD1 | PC_REP_SPD0 | PB_RESET_2081 | +			PB_MAI_ALL; +	immr->im_cpm.cp_pbpar &= ~reg; +	immr->im_cpm.cp_pbodr &= ~reg; +	immr->im_cpm.cp_pbdat &= ~reg;	/* all 0 */ +	immr->im_cpm.cp_pbdir |= reg; + +	/* Check hardware revision */ +	if ((immr->im_ioport.iop_pcdat & 0x0003) == 0x0003) { +		/* +		 * Revision 3.x hardware +		 */ +		revision = 3; + +		immr->im_ioport.iop_pcdat = 0x0240; +		immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14);	/* = 0x0246 */ +		immr->im_ioport.iop_pcdat |= PC_REP_RES; +	} else { +		immr->im_ioport.iop_pcdat = 0x0002; +		immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_RES | PC_BIT14 | PC_BIT15);	/* = 0x0207 */ + +		if ((immr->im_ioport.iop_pcdat & PC_REP_SPD) == 0) { +			/* +			 * Revision 2.x hardware: PC9 connected to PB21 +			 */ +			revision = 2; + +			if (ethspeed == 0) { +				/* both 10 and 100 Mbps allowed: +				 * select 10 Mbps and autonegotiation +				 */ +				puts ("  [10+100]"); +				immr->im_cpm.cp_pbdat = 0;	/* SPD1:SPD0 = 0:0 - autonegot. */ +				speed = 10; +			} else if (ethspeed == 10) { +				/* we are asked for 10 Mbps, +				 * so select 10 Mbps +				 */ +				puts ("  [10]"); +				immr->im_cpm.cp_pbdat = 0;	/* ??? */ +				speed = 10; +			} else { +				/* anything else: +				 * select 100 Mbps +				 */ +				puts ("  [100]"); +				immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1; +				/* SPD1:SPD0 = 1:1 - 100 Mbps */ +				speed = 100; +			} +			immr->im_ioport.iop_pcdat |= (PC_REP_RES | PC_BIT14); + +			/* must be run from RAM  */ +			/* start_lxt980 (speed); */ +		/*************************/ +		} else { +			/* +			 * Revision 1.x hardware +			 */ +			revision = 1; + +			immr->im_ioport.iop_pcdat = PC_REP_MGRPRS | PC_BIT14;	/* = 0x0202 */ +			immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14 | PC_BIT15);	/* = 0x0247 */ + +			if (ethspeed == 0) { +				/* both 10 and 100 Mbps allowed: +				 * select 100 Mbps and autonegotiation +				 */ +				puts ("  [10+100]"); +				immr->im_cpm.cp_pbdat = 0;	/* SPD1:SPD0 = 0:0 - autonegot. */ +				immr->im_ioport.iop_pcdat |= PC_REP_SPD; +			} else if (ethspeed == 10) { +				/* we are asked for 10 Mbps, +				   * so select 10 Mbps +				 */ +				puts ("  [10]"); +				immr->im_cpm.cp_pbdat = PC_REP_SPD0;	/* SPD1:SPD0 = 0:1 - 10 Mbps */ +			} else { +				/* anything else: +				   * select 100 Mbps +				 */ +				puts ("  [100]"); +				immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1; +				/* SPD1:SPD0 = 1:1 - 100 Mbps */ +				immr->im_ioport.iop_pcdat |= PC_REP_SPD; +			} + +			immr->im_ioport.iop_pcdat |= PC_REP_RES; +		} +	} +	SHOW_BOOT_PROGRESS(BOOTSTAGE_ID_CHECK_MAGIC); + +	return ((revision << 16) | (speed & 0xFFFF)); +} + +/* ------------------------------------------------------------------------- */ + +#define SCC_SM		1			/* Index => SCC2 */ +#define	PROFF		PROFF_SCC2 + +#define SMI_MSGLEN	8			/* Length of SMI Messages        */ + +#define PHYGPCR_ADDR	0x109	/* Port Enable               */ +#define PHYPCR_ADDR	0x132		/* PHY Port Control Reg. (port 1)    */ +#define LEDPCR_ADDR	0x141		/* LED Port Control Reg.         */ +#define RPRESET_ADDR	0x144	/* Repeater Reset            */ + +#define PHYPCR_SPEED	0x2000	/* on for 100 Mbps, off for 10 Mbps  */ +#define PHYPCR_AN	0x1000		/* on to enable  Auto-Negotiation    */ +#define PHYPCR_REST_AN	0x0200	/* on to restart Auto-Negotiation    */ +#define PHYPCR_FDX	0x0100		/* on for Full Duplex, off for HDX   */ +#define PHYPCR_COLT	0x0080		/* on to enable COL signal test      */ + +/* ------------------------------------------------------------------------- */ + +/* + * Must run from RAM: + * uses parameter RAM area which is used for stack while running from ROM + */ +void hermes_start_lxt980 (int speed) +{ +	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; +	volatile cpm8xx_t *cp = (cpm8xx_t *) & (immr->im_cpm); +	volatile scc_t *sp = (scc_t *) & (cp->cp_scc[SCC_SM]); +	volatile cbd_t *bd; +	volatile hdlc_pram_t *hp; +	uchar smimsg[SMI_MSGLEN]; +	ushort phypcrval; +	uint bd_off; +	int pnr; + +	printf ("LXT9880: %3d Mbps\n", speed); + +	immr->im_ioport.iop_paodr |= 0x0008;	/* init PAODR: PA12 (TXD2) open drain */ +	immr->im_ioport.iop_papar |= 0x400c;	/* init PAPAR: TXD2, RXD2, BRGO4 */ +	immr->im_ioport.iop_padir &= 0xbff3;	/* init PADIR: BRGO4 */ +	immr->im_ioport.iop_padir |= 0x4000; + +	/* get temporary BD; no need for permanent alloc */ +	bd_off = dpram_base_align (8); + +	bd = (cbd_t *) (immr->im_cpm.cp_dpmem + bd_off); + +	bd->cbd_bufaddr = 0; +	bd->cbd_datlen = 0; +	bd->cbd_sc = BD_SC_WRAP | BD_SC_LAST | BD_SC_INTRPT | BD_SC_TC; + +	/* init. baudrate generator BRG4 */ +	cp->cp_brgc4 = (0x00010000 | (50 << 1));	/* output 1 MHz */ + +	cp->cp_sicr &= 0xFFFF00FF;	/* SICR: mask SCC2 */ +	cp->cp_sicr |= 0x00001B00;	/* SICR: SCC2 clk BRG4 */ + +	/* init SCC_SM register */ +	sp->scc_psmr = 0x0000;		/* init PSMR: no additional flags */ +	sp->scc_todr = 0x0000; +	sp->scc_dsr = 0x7e7e; + +	/* init. SCC_SM parameter area */ +	hp = (hdlc_pram_t *) & cp->cp_dparam[PROFF]; + +	hp->tbase = bd_off;			/* offset from beginning of DPRAM */ + +	hp->rfcr = 0x18; +	hp->tfcr = 0x18; +	hp->mrblr = 10; + +	hp->c_mask = 0x0000f0b8; +	hp->c_pres = 0x0000ffff; + +	hp->disfc = 0; +	hp->crcec = 0; +	hp->abtsc = 0; +	hp->nmarc = 0; +	hp->retrc = 0; + +	hp->mflr = 10; + +	hp->rfthr = 1; + +	hp->hmask = 0; +	hp->haddr1 = 0; +	hp->haddr2 = 0; +	hp->haddr3 = 0; +	hp->haddr4 = 0; + +	cp->cp_cpcr = SCC_SM << 6 | 0x0001;	/* SCC_SM: init TX/RX params */ +	while (cp->cp_cpcr & CPM_CR_FLG); + +	/* clear all outstanding SCC events */ +	sp->scc_scce = ~0; + +	/* enable transmitter: GSMR_L: TPL=2(16bits), TPP=3(all ones), ENT */ +	sp->scc_gsmrh = 0; +	sp->scc_gsmrl |= SCC_GSMRL_TPL_16 | SCC_GSMRL_TPP_ALL1 | +			SCC_GSMRL_ENT | SCC_GSMRL_MODE_HDLC; + +#if 0 +	smimsg[0] = 0x00;			/* CHIP/HUB ID */ +	smimsg[1] = 0x38;			/* WRITE CMD */ +	smimsg[2] = (RPRESET_ADDR << 4) & 0xf0; +	smimsg[3] = RPRESET_ADDR >> 4; +	smimsg[4] = 0x01; +	smimsg[5] = 0x00; +	smimsg[6] = 0x00; +	smimsg[7] = 0x00; + +	send_smi_frame (sp, bd, smimsg); +#endif + +	smimsg[0] = 0x7f;			/* BROADCAST */ +	smimsg[1] = 0x34;			/* ASSIGN HUB ID */ +	smimsg[2] = 0x00; +	smimsg[3] = 0x00; +	smimsg[4] = 0x00;			/* HUB ID = 0 */ +	smimsg[5] = 0x00; +	smimsg[6] = 0x00; +	smimsg[7] = 0x00; + +	send_smi_frame (sp, bd, smimsg); + +	smimsg[0] = 0x7f;			/* BROADCAST */ +	smimsg[1] = 0x3c;			/* SET ARBOUT TO 0 */ +	smimsg[2] = 0x00;			/* ADDRESS = 0 */ +	smimsg[3] = 0x00; +	smimsg[4] = 0x00;			/* DATA = 0 */ +	smimsg[5] = 0x00; +	smimsg[6] = 0x00; +	smimsg[7] = 0x00; + +	send_smi_frame (sp, bd, smimsg); + +	if (speed == 100) { +		phypcrval = PHYPCR_SPEED;	/* 100 MBIT, disable autoneg. */ +	} else { +		phypcrval = 0;			/* 10 MBIT, disable autoneg. */ +	} + +	/* send MSGs */ +	for (pnr = 0; pnr < 8; pnr++) { +		smimsg[0] = 0x00;		/* CHIP/HUB ID */ +		smimsg[1] = 0x38;		/* WRITE CMD */ +		smimsg[2] = ((PHYPCR_ADDR + pnr) << 4) & 0xf0; +		smimsg[3] = (PHYPCR_ADDR + pnr) >> 4; +		smimsg[4] = (unsigned char) (phypcrval & 0xff); +		smimsg[5] = (unsigned char) (phypcrval >> 8); +		smimsg[6] = 0x00; +		smimsg[7] = 0x00; + +		send_smi_frame (sp, bd, smimsg); +	} + +	smimsg[0] = 0x00;			/* CHIP/HUB ID */ +	smimsg[1] = 0x38;			/* WRITE CMD */ +	smimsg[2] = (PHYGPCR_ADDR << 4) & 0xf0; +	smimsg[3] = PHYGPCR_ADDR >> 4; +	smimsg[4] = 0xff;			/* enable port 1-8 */ +	smimsg[5] = 0x01;			/* enable MII1 (0x01) */ +	smimsg[6] = 0x00; +	smimsg[7] = 0x00; + +	send_smi_frame (sp, bd, smimsg); + +	smimsg[0] = 0x00;			/* CHIP/HUB ID */ +	smimsg[1] = 0x38;			/* WRITE CMD */ +	smimsg[2] = (LEDPCR_ADDR << 4) & 0xf0; +	smimsg[3] = LEDPCR_ADDR >> 4; +	smimsg[4] = 0xaa;			/* Port 1-8 Conf.bits = 10 (Hardware control) */ +	smimsg[5] = 0xaa; +	smimsg[6] = 0x00; +	smimsg[7] = 0x00; + +	send_smi_frame (sp, bd, smimsg); + +	/* +	 * Disable Transmitter (so that we can free the BD, too) +	 */ +	sp->scc_gsmrl &= ~SCC_GSMRL_ENT; +} + +/* ------------------------------------------------------------------------- */ + +static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd, +							uchar * msg) +{ +#ifdef DEBUG +	unsigned hub, chip, cmd, length, addr; + +	hub = msg[0] & 0x1F; +	chip = msg[0] >> 5; +	cmd = msg[1] & 0x1F; +	length = (msg[1] >> 5) | ((msg[2] & 0x0F) << 3); +	addr = (msg[2] >> 4) | (msg[3] << 4); + +	printf ("SMI send: Hub %02x Chip %x Cmd %02x Len %d Addr %03x: " +			"%02x %02x %02x %02x\n", +			hub, chip, cmd, length, addr, msg[4], msg[5], msg[6], msg[7]); +#endif /* DEBUG */ + +	bd->cbd_bufaddr = (uint) msg; +	bd->cbd_datlen = SMI_MSGLEN; +	bd->cbd_sc |= BD_SC_READY; + +	/* wait for msg transmitted */ +	while ((sp->scc_scce & 0x0002) == 0); +	/* clear all events */ +	sp->scc_scce = ~0; +} + +/* ------------------------------------------------------------------------- */ + +void show_boot_progress (int status) +{ +	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; + +	/* let things compatible */ +	if (status < -BOOTSTAGE_ID_POST_FAIL_R) +		status = -1; +	status ^= 0x0F; +	status = (status & 0x0F) << 14; +	immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & ~PB_LED_ALL) | status; +} + +/* ------------------------------------------------------------------------- */ diff --git a/roms/u-boot/board/hermes/u-boot.lds b/roms/u-boot/board/hermes/u-boot.lds new file mode 100644 index 00000000..03098603 --- /dev/null +++ b/roms/u-boot/board/hermes/u-boot.lds @@ -0,0 +1,88 @@ +/* + * (C) Copyright 2000-2010 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +OUTPUT_ARCH(powerpc) + +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .text      : +  { +    /* WARNING - the following is hand-optimized to fit within	*/ +    /* the sector layout of our flash chips!	XXX FIXME XXX	*/ +    arch/powerpc/cpu/mpc8xx/start.o	(.text*) +    arch/powerpc/cpu/mpc8xx/traps.o	(.text*) +    board/hermes/built-in.o		(.text*) + +    . = env_offset; +    common/env_embedded.o		(.text*) + +    *(.text*) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) +  } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x00FF) & 0xFFFFFF00; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    _GOT2_TABLE_ = .; +    KEEP(*(.got2)) +    KEEP(*(.got)) +    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4); +    _FIXUP_TABLE_ = .; +    KEEP(*(.fixup)) +  } +  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data*) +    *(.sdata*) +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  . = .; + +  . = ALIGN(4); +  .u_boot_list : { +	KEEP(*(SORT(.u_boot_list*))); +  } + + +  . = .; +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(256); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(256); +  __init_end = .; + +  __bss_start = .; +  .bss (NOLOAD)       : +  { +   *(.bss*) +   *(.sbss*) +   *(COMMON) +   . = ALIGN(4); +  } +  __bss_end = . ; +  PROVIDE (end = .); +} diff --git a/roms/u-boot/board/hermes/u-boot.lds.debug b/roms/u-boot/board/hermes/u-boot.lds.debug new file mode 100644 index 00000000..f34c07ba --- /dev/null +++ b/roms/u-boot/board/hermes/u-boot.lds.debug @@ -0,0 +1,121 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +OUTPUT_ARCH(powerpc) +/* Do we need any of these for elf? +   __DYNAMIC = 0;    */ +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .interp : { *(.interp) } +  .hash          : { *(.hash)		} +  .dynsym        : { *(.dynsym)		} +  .dynstr        : { *(.dynstr)		} +  .rel.text      : { *(.rel.text)		} +  .rela.text     : { *(.rela.text)	} +  .rel.data      : { *(.rel.data)		} +  .rela.data     : { *(.rela.data)	} +  .rel.rodata    : { *(.rel.rodata)	} +  .rela.rodata   : { *(.rela.rodata)	} +  .rel.got       : { *(.rel.got)		} +  .rela.got      : { *(.rela.got)		} +  .rel.ctors     : { *(.rel.ctors)	} +  .rela.ctors    : { *(.rela.ctors)	} +  .rel.dtors     : { *(.rel.dtors)	} +  .rela.dtors    : { *(.rela.dtors)	} +  .rel.bss       : { *(.rel.bss)		} +  .rela.bss      : { *(.rela.bss)		} +  .rel.plt       : { *(.rel.plt)		} +  .rela.plt      : { *(.rela.plt)		} +  .init          : { *(.init)	} +  .plt : { *(.plt) } +  .text      : +  { +    /* WARNING - the following is hand-optimized to fit within	*/ +    /* the sector layout of our flash chips!	XXX FIXME XXX	*/ + +    arch/powerpc/cpu/mpc8xx/start.o	(.text) +    arch/powerpc/lib/ppcstring.o	(.text) +    arch/powerpc/cpu/mpc8xx/interrupts.o (.text) +    arch/powerpc/lib/time.o		(.text) +    arch/powerpc/lib/ticks.o		(.text) +    . = env_offset; +    common/env_embedded.o(.text) + +    *(.text) +    *(.got1) +  } +  _etext = .; +  PROVIDE (etext = .); +  .rodata    : +  { +    *(.rodata) +    *(.rodata1) +    *(.rodata.str1.4) +    *(.eh_frame) +  } +  .fini      : { *(.fini)    } =0 +  .ctors     : { *(.ctors)   } +  .dtors     : { *(.dtors)   } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x0FFF) & 0xFFFFF000; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    *(.got) +    _GOT2_TABLE_ = .; +    *(.got2) +    _FIXUP_TABLE_ = .; +    *(.fixup) +  } +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2; +  __fixup_entries = (. - _FIXUP_TABLE_)>>2; + +  .data    : +  { +    *(.data) +    *(.data1) +    *(.sdata) +    *(.sdata2) +    *(.dynamic) +    CONSTRUCTORS +  } +  _edata  =  .; +  PROVIDE (edata = .); + + +  . = ALIGN(4); +  .u_boot_list : { +	KEEP(*(SORT(.u_boot_list*))); +  } + + +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(4096); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(4096); +  __init_end = .; + +  __bss_start = .; +  .bss       : +  { +   *(.sbss) *(.scommon) +   *(.dynbss) +   *(.bss) +   *(COMMON) +  } +  __bss_end = . ; +  PROVIDE (end = .); +}  | 
