mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			285 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * (C) Copyright 2003
 | 
						|
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 | 
						|
 *
 | 
						|
 * See file CREDITS for list of people who contributed to this
 | 
						|
 * project.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or
 | 
						|
 * modify it under the terms of the GNU General Public License as
 | 
						|
 * published by the Free Software Foundation; either version 2 of
 | 
						|
 * the License, or (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; if not, write to the Free Software
 | 
						|
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 | 
						|
 * MA 02111-1307 USA
 | 
						|
 */
 | 
						|
 | 
						|
#include <common.h>
 | 
						|
#include <command.h>
 | 
						|
#include <netdev.h>
 | 
						|
#include <asm/inca-ip.h>
 | 
						|
#include <asm/regdef.h>
 | 
						|
#include <asm/mipsregs.h>
 | 
						|
#include <asm/io.h>
 | 
						|
#include <asm/addrspace.h>
 | 
						|
#include <asm/cacheops.h>
 | 
						|
#include <asm/reboot.h>
 | 
						|
 | 
						|
#include "sconsole.h"
 | 
						|
 | 
						|
#define cache_unroll(base,op)		\
 | 
						|
	__asm__ __volatile__("		\
 | 
						|
		.set noreorder;		\
 | 
						|
		.set mips3;		\
 | 
						|
		cache %1, (%0);		\
 | 
						|
		.set mips0;		\
 | 
						|
		.set reorder"		\
 | 
						|
		:			\
 | 
						|
		: "r" (base),		\
 | 
						|
		  "i" (op));
 | 
						|
 | 
						|
typedef void (*FUNCPTR)(ulong *source, ulong *destination, ulong nlongs);
 | 
						|
 | 
						|
extern void	asc_serial_init		(void);
 | 
						|
extern void	asc_serial_putc		(char);
 | 
						|
extern void	asc_serial_puts		(const char *);
 | 
						|
extern int	asc_serial_getc		(void);
 | 
						|
extern int	asc_serial_tstc		(void);
 | 
						|
extern void	asc_serial_setbrg	(void);
 | 
						|
 | 
						|
void _machine_restart(void)
 | 
						|
{
 | 
						|
	void (*f)(void) = (void *) 0xbfc00000;
 | 
						|
 | 
						|
	f();
 | 
						|
}
 | 
						|
 | 
						|
static void sdram_timing_init (ulong size)
 | 
						|
{
 | 
						|
	register uint pass;
 | 
						|
	register uint done;
 | 
						|
	register uint count;
 | 
						|
	register uint p0, p1, p2, p3, p4;
 | 
						|
	register uint addr;
 | 
						|
 | 
						|
#define WRITE_MC_IOGP_1 *(uint *)0xbf800800 = (p1<<14)+(p2<<13)+(p4<<8)+(p0<<4)+p3;
 | 
						|
#define WRITE_MC_IOGP_2 *(uint *)0xbf800800 = (p1<<14)+(p2<<13)+((p4-16)<<8)+(p0<<4)+p3;
 | 
						|
 | 
						|
	done = 0;
 | 
						|
	p0 = 2;
 | 
						|
	while (p0 < 4 && done == 0) {
 | 
						|
	    p1 = 0;
 | 
						|
	    while (p1 < 2 && done == 0) {
 | 
						|
		p2 = 0;
 | 
						|
		while (p2 < 2 && done == 0) {
 | 
						|
		    p3 = 0;
 | 
						|
		    while (p3 < 16 && done == 0) {
 | 
						|
			count = 0;
 | 
						|
			p4 = 0;
 | 
						|
			while (p4 < 32 && done == 0) {
 | 
						|
			    WRITE_MC_IOGP_1;
 | 
						|
 | 
						|
			    for (addr = CKSEG1 + 0x4000;
 | 
						|
				 addr < CKSEG1ADDR (size);
 | 
						|
				 addr = addr + 4) {
 | 
						|
					*(uint *) addr = 0xaa55aa55;
 | 
						|
			    }
 | 
						|
 | 
						|
			    pass = 1;
 | 
						|
 | 
						|
			    for (addr = CKSEG1 + 0x4000;
 | 
						|
				 addr < CKSEG1ADDR (size) && pass == 1;
 | 
						|
				 addr = addr + 4) {
 | 
						|
					if (*(uint *) addr != 0xaa55aa55)
 | 
						|
						pass = 0;
 | 
						|
			    }
 | 
						|
 | 
						|
			    if (pass == 1) {
 | 
						|
				count++;
 | 
						|
			    } else {
 | 
						|
				count = 0;
 | 
						|
			    }
 | 
						|
 | 
						|
			    if (count == 32) {
 | 
						|
				WRITE_MC_IOGP_2;
 | 
						|
				done = 1;
 | 
						|
			    }
 | 
						|
			    p4++;
 | 
						|
			}
 | 
						|
			p3++;
 | 
						|
		    }
 | 
						|
		    p2++;
 | 
						|
		}
 | 
						|
		p1++;
 | 
						|
	    }
 | 
						|
	    p0++;
 | 
						|
	    if (p0 == 1)
 | 
						|
		p0++;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
phys_size_t initdram(int board_type)
 | 
						|
{
 | 
						|
	/* The only supported number of SDRAM banks is 4.
 | 
						|
	 */
 | 
						|
#define CONFIG_SYS_NB	4
 | 
						|
 | 
						|
	ulong	cfgpb0	= *INCA_IP_SDRAM_MC_CFGPB0;
 | 
						|
	ulong	cfgdw	= *INCA_IP_SDRAM_MC_CFGDW;
 | 
						|
	int	cols	= cfgpb0 & 0xF;
 | 
						|
	int	rows	= (cfgpb0 & 0xF0) >> 4;
 | 
						|
	int	dw	= cfgdw & 0xF;
 | 
						|
	ulong	size	= (1 << (rows + cols)) * (1 << (dw - 1)) * CONFIG_SYS_NB;
 | 
						|
	void (*  sdram_init) (ulong);
 | 
						|
 | 
						|
	sdram_init = (void (*)(ulong)) CKSEG0ADDR(&sdram_timing_init);
 | 
						|
 | 
						|
	sdram_init(0x10000);
 | 
						|
 | 
						|
	return size;
 | 
						|
}
 | 
						|
 | 
						|
int checkboard (void)
 | 
						|
{
 | 
						|
 | 
						|
	unsigned long chipid = *(unsigned long *)0xB800C800;
 | 
						|
 | 
						|
	printf ("Board: Purple PLB 2800 chip version %ld, ", chipid & 0xF);
 | 
						|
 | 
						|
	printf("CPU Speed %d MHz\n", CPU_CLOCK_RATE/1000000);
 | 
						|
 | 
						|
	set_io_port_base(0);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
int misc_init_r (void)
 | 
						|
{
 | 
						|
	asc_serial_init ();
 | 
						|
 | 
						|
	sconsole_putc   = asc_serial_putc;
 | 
						|
	sconsole_puts   = asc_serial_puts;
 | 
						|
	sconsole_getc   = asc_serial_getc;
 | 
						|
	sconsole_tstc   = asc_serial_tstc;
 | 
						|
	sconsole_setbrg = asc_serial_setbrg;
 | 
						|
 | 
						|
	sconsole_flush ();
 | 
						|
	return (0);
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
*
 | 
						|
* copydwords - copy one buffer to another a long at a time
 | 
						|
*
 | 
						|
* This routine copies the first <nlongs> longs from <source> to <destination>.
 | 
						|
*/
 | 
						|
static void copydwords (ulong *source, ulong *destination, ulong nlongs)
 | 
						|
{
 | 
						|
	ulong temp,temp1;
 | 
						|
	ulong *dstend = destination + nlongs;
 | 
						|
 | 
						|
	while (destination < dstend) {
 | 
						|
		temp = *source++;
 | 
						|
		/* dummy read from sdram */
 | 
						|
		temp1 = *(ulong *)0xa0000000;
 | 
						|
		/* avoid optimization from compliler */
 | 
						|
		*(ulong *)0xbf0081f8 = temp1 + temp;
 | 
						|
		*destination++ = temp;
 | 
						|
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
*
 | 
						|
* copyLongs - copy one buffer to another a long at a time
 | 
						|
*
 | 
						|
* This routine copies the first <nlongs> longs from <source> to <destination>.
 | 
						|
*/
 | 
						|
static void copyLongs (ulong *source, ulong *destination, ulong nlongs)
 | 
						|
{
 | 
						|
	FUNCPTR absEntry;
 | 
						|
 | 
						|
	absEntry = (FUNCPTR)(0xbf008000+((ulong)copydwords & 0x7));
 | 
						|
	absEntry(source, destination, nlongs);
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
*
 | 
						|
* programLoad - load program into ram
 | 
						|
*
 | 
						|
* This routine load copydwords into ram
 | 
						|
*
 | 
						|
*/
 | 
						|
static void programLoad(void)
 | 
						|
{
 | 
						|
	FUNCPTR absEntry;
 | 
						|
	ulong *src,*dst;
 | 
						|
 | 
						|
	src = (ulong *)(TEXT_BASE + 0x428);
 | 
						|
	dst = (ulong *)0xbf0081d0;
 | 
						|
 | 
						|
	absEntry = (FUNCPTR)(TEXT_BASE + 0x400);
 | 
						|
	absEntry(src,dst,0x6);
 | 
						|
 | 
						|
	src = (ulong *)((ulong)copydwords & 0xfffffff8);
 | 
						|
	dst = (ulong *)0xbf008000;
 | 
						|
 | 
						|
	absEntry(src,dst,0x38);
 | 
						|
}
 | 
						|
 | 
						|
/*******************************************************************************
 | 
						|
*
 | 
						|
* copy_code - copy u-boot image from flash to RAM
 | 
						|
*
 | 
						|
* This routine is needed to solve flash problems on this board
 | 
						|
*
 | 
						|
*/
 | 
						|
void copy_code (ulong dest_addr)
 | 
						|
{
 | 
						|
	extern long uboot_end_data;
 | 
						|
	unsigned long start;
 | 
						|
	unsigned long end;
 | 
						|
 | 
						|
	/* load copydwords into ram
 | 
						|
	 */
 | 
						|
	programLoad();
 | 
						|
 | 
						|
	/* copy u-boot code
 | 
						|
	 */
 | 
						|
	copyLongs((ulong *)CONFIG_SYS_MONITOR_BASE,
 | 
						|
		  (ulong *)dest_addr,
 | 
						|
		  ((ulong)&uboot_end_data - CONFIG_SYS_MONITOR_BASE + 3) / 4);
 | 
						|
 | 
						|
 | 
						|
	/* flush caches
 | 
						|
	 */
 | 
						|
 | 
						|
	start = CKSEG0;
 | 
						|
	end = start + CONFIG_SYS_DCACHE_SIZE;
 | 
						|
	while(start < end) {
 | 
						|
		cache_unroll(start,Index_Writeback_Inv_D);
 | 
						|
		start += CONFIG_SYS_CACHELINE_SIZE;
 | 
						|
	}
 | 
						|
 | 
						|
	start = CKSEG0;
 | 
						|
	end = start + CONFIG_SYS_ICACHE_SIZE;
 | 
						|
	while(start < end) {
 | 
						|
		cache_unroll(start,Index_Invalidate_I);
 | 
						|
		start += CONFIG_SYS_CACHELINE_SIZE;
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
#ifdef CONFIG_PLB2800_ETHER
 | 
						|
int board_eth_init(bd_t *bis)
 | 
						|
{
 | 
						|
	return plb2800_eth_initialize(bis);
 | 
						|
}
 | 
						|
#endif
 |