diff options
Diffstat (limited to 'arch/ppc/cpu/mpc824x/cpu.c')
| -rw-r--r-- | arch/ppc/cpu/mpc824x/cpu.c | 280 | 
1 files changed, 280 insertions, 0 deletions
| diff --git a/arch/ppc/cpu/mpc824x/cpu.c b/arch/ppc/cpu/mpc824x/cpu.c new file mode 100644 index 000000000..08f6a947f --- /dev/null +++ b/arch/ppc/cpu/mpc824x/cpu.c @@ -0,0 +1,280 @@ +/* + * (C) Copyright 2000 - 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <config.h> +#include <mpc824x.h> +#include <common.h> +#include <command.h> + +DECLARE_GLOBAL_DATA_PTR; + +int checkcpu (void) +{ +	unsigned int pvr = get_pvr (); +	unsigned int version = pvr >> 16; +	unsigned char revision; +	ulong clock = gd->cpu_clk; +	char buf[32]; + +	puts ("CPU:   "); + +	switch (version) { +	case CPU_TYPE_8240: +		puts ("MPC8240"); +		break; + +	case CPU_TYPE_8245: +		puts ("MPC8245"); +		break; + +	default: +		return -1;		/*not valid for this source */ +	} + +	CONFIG_READ_BYTE (REVID, revision); + +	if (revision) { +		printf (" Revision %d.%d", +			(revision & 0xf0) >> 4, +			(revision & 0x0f)); +	} else { +		return -1;		/* no valid CPU revision info */ +	} + +	printf (" at %s MHz:", strmhz (buf, clock)); + +	printf (" %u kB I-Cache", checkicache () >> 10); +	printf (" %u kB D-Cache", checkdcache () >> 10); + +	puts ("\n"); + +	return 0; +} + +/* ------------------------------------------------------------------------- */ +/* L1 i-cache                                                                */ + +int checkicache (void) +{ +	 /*TODO*/ +	 return 128 * 4 * 32; +}; + +/* ------------------------------------------------------------------------- */ +/* L1 d-cache                                                                */ + +int checkdcache (void) +{ +	 /*TODO*/ +	 return 128 * 4 * 32; + +}; + +/*------------------------------------------------------------------- */ + +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	ulong msr, addr; + +	/* Interrupts and MMU off */ +	__asm__ ("mtspr    81, 0"); + +	/* Interrupts and MMU off */ +	__asm__ __volatile__ ("mfmsr    %0":"=r" (msr):); + +	msr &= ~0x1030; +	__asm__ __volatile__ ("mtmsr    %0"::"r" (msr)); + +	/* +	 * Trying to execute the next instruction at a non-existing address +	 * should cause a machine check, resulting in reset +	 */ +#ifdef CONFIG_SYS_RESET_ADDRESS +	addr = CONFIG_SYS_RESET_ADDRESS; +#else +	/* +	 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address, +	 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid +	 * address. Better pick an address known to be invalid on +	 * your system and assign it to CONFIG_SYS_RESET_ADDRESS. +	 * "(ulong)-1" used to be a good choice for many systems... +	 */ +	addr = CONFIG_SYS_MONITOR_BASE - sizeof (ulong); +#endif +	((void (*)(void)) addr) (); +	return 1; + +} + +/* ------------------------------------------------------------------------- */ + +/* + * Get timebase clock frequency (like cpu_clk in Hz) + * This is the sys_logic_clk (memory bus) divided by 4 + */ +unsigned long get_tbclk (void) +{ +	return ((get_bus_freq (0) + 2L) / 4L); +} + +/* ------------------------------------------------------------------------- */ + +/* + * The MPC824x has an integrated PCI controller known as the MPC107. + * The following are MPC107 Bridge Controller and PCI Support functions + * + */ + +/* + *  This procedure reads a 32-bit address MPC107 register, and returns + *  a 32 bit value.  It swaps the address to little endian before + *  writing it to config address, and swaps the value to big endian + *  before returning to the caller. + */ +unsigned int mpc824x_mpc107_getreg (unsigned int regNum) +{ +	unsigned int temp; + +	/* swap the addr. to little endian */ +	*(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum); +	temp = *(volatile unsigned int *) CHRP_REG_DATA; +	return PCISWAP (temp);		/* swap the data upon return */ +} + +/* + *  This procedure writes a 32-bit address MPC107 register.  It swaps + *  the address to little endian before writing it to config address. + */ + +void mpc824x_mpc107_setreg (unsigned int regNum, unsigned int regVal) +{ +	/* swap the addr. to little endian */ +	*(volatile unsigned int *) CHRP_REG_ADDR = PCISWAP (regNum); +	*(volatile unsigned int *) CHRP_REG_DATA = PCISWAP (regVal); +	return; +} + + +/* + *  Write a byte (8 bits) to a memory location. + */ +void mpc824x_mpc107_write8 (unsigned int addr, unsigned char data) +{ +	*(unsigned char *) addr = data; +	__asm__ ("sync"); +} + +/* + *  Write a word (16 bits) to a memory location after the value + *  has been byte swapped (big to little endian or vice versa) + */ + +void mpc824x_mpc107_write16 (unsigned int address, unsigned short data) +{ +	*(volatile unsigned short *) address = BYTE_SWAP_16_BIT (data); +	__asm__ ("sync"); +} + +/* + *  Write a long word (32 bits) to a memory location after the value + *  has been byte swapped (big to little endian or vice versa) + */ + +void mpc824x_mpc107_write32 (unsigned int address, unsigned int data) +{ +	*(volatile unsigned int *) address = LONGSWAP (data); +	__asm__ ("sync"); +} + +/* + *  Read a byte (8 bits) from a memory location. + */ +unsigned char mpc824x_mpc107_read8 (unsigned int addr) +{ +	return *(volatile unsigned char *) addr; +} + + +/* + *  Read a word (16 bits) from a memory location, and byte swap the + *  value before returning to the caller. + */ +unsigned short mpc824x_mpc107_read16 (unsigned int address) +{ +	unsigned short retVal; + +	retVal = BYTE_SWAP_16_BIT (*(unsigned short *) address); +	return retVal; +} + + +/* + *  Read a long word (32 bits) from a memory location, and byte + *  swap the value before returning to the caller. + */ +unsigned int mpc824x_mpc107_read32 (unsigned int address) +{ +	unsigned int retVal; + +	retVal = LONGSWAP (*(unsigned int *) address); +	return (retVal); +} + + +/* + *  Read a register in the Embedded Utilities Memory Block address + *  space. + *  Input: regNum - register number + utility base address.  Example, + *         the base address of EPIC is 0x40000, the register number + *	   being passed is 0x40000+the address of the target register. + *	   (See epic.h for register addresses). + *  Output:  The 32 bit little endian value of the register. + */ + +unsigned int mpc824x_eummbar_read (unsigned int regNum) +{ +	unsigned int temp; + +	temp = *(volatile unsigned int *) (EUMBBAR_VAL + regNum); +	temp = PCISWAP (temp); +	return temp; +} + + +/* + *  Write a value to a register in the Embedded Utilities Memory + *  Block address space. + *  Input: regNum - register number + utility base address.  Example, + *                  the base address of EPIC is 0x40000, the register + *	            number is 0x40000+the address of the target register. + *	            (See epic.h for register addresses). + *         regVal - value to be written to the register. + */ + +void mpc824x_eummbar_write (unsigned int regNum, unsigned int regVal) +{ +	*(volatile unsigned int *) (EUMBBAR_VAL + regNum) = PCISWAP (regVal); +	return; +} + +/* ------------------------------------------------------------------------- */ |