/*
 * (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>

int checkcpu (void)
{
	DECLARE_GLOBAL_DATA_PTR;

	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 CFG_RESET_ADDRESS
	addr = CFG_RESET_ADDRESS;
#else
	/*
	 * note: when CFG_MONITOR_BASE points to a RAM address,
	 * CFG_MONITOR_BASE - sizeof (ulong) is usually a valid
	 * address. Better pick an address known to be invalid on
	 * your system and assign it to CFG_RESET_ADDRESS.
	 * "(ulong)-1" used to be a good choice for many systems...
	 */
	addr = CFG_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;
}

/* ------------------------------------------------------------------------- */
