/*
 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Andreas Heppel <aheppel@sysgo.de>
 * (C) Copyright 2001 ELTEC Elektronik AG
 * Frank Gottschling <fgottschling@eltec.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 <mpc106.h>
#include <mk48t59.h>
#include <74xx_7xx.h>
#include <ns87308.h>
#include <video_fb.h>
#include <netdev.h>

DECLARE_GLOBAL_DATA_PTR;

/*---------------------------------------------------------------------------*/
/*
 * Get Bus clock frequency
 */
ulong bab7xx_get_bus_freq (void)
{
	/*
	 * The GPIO Port 1 on BAB7xx reflects the bus speed.
	 */
	volatile struct GPIO *gpio =
		(struct GPIO *) (CONFIG_SYS_ISA_IO + CONFIG_SYS_NS87308_GPIO_BASE);

	unsigned char data = gpio->dta1;

	if (data & 0x02)
		return 66666666;

	return 83333333;
}

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

/*
 * Measure CPU clock speed (core clock GCLK1) (Approx. GCLK frequency in Hz)
 */
ulong bab7xx_get_gclk_freq (void)
{
	static const int pllratio_to_factor[] = {
		00, 75, 70, 00, 20, 65, 100, 45, 30, 55, 40, 50, 80, 60, 35,
			00,
	};

	return pllratio_to_factor[get_hid1 () >> 28] *
		(bab7xx_get_bus_freq () / 10);
}

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

int checkcpu (void)
{
	uint pvr = get_pvr ();

	printf ("MPC7xx V%d.%d", (pvr >> 8) & 0xFF, pvr & 0xFF);
	printf (" at %ld / %ld MHz\n", bab7xx_get_gclk_freq () / 1000000,
		bab7xx_get_bus_freq () / 1000000);

	return (0);
}

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

int checkboard (void)
{
#ifdef CONFIG_SYS_ADDRESS_MAP_A
	puts ("Board: ELTEC BAB7xx PReP\n");
#else
	puts ("Board: ELTEC BAB7xx CHRP\n");
#endif
	return (0);
}

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

int checkflash (void)
{
	/* TODO: XXX XXX XXX */
	printf ("2 MB ## Test not implemented yet ##\n");
	return (0);
}

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


static unsigned int mpc106_read_cfg_dword (unsigned int reg)
{
	unsigned int reg_addr = MPC106_REG | (reg & 0xFFFFFFFC);

	out32r (MPC106_REG_ADDR, reg_addr);

	return (in32r (MPC106_REG_DATA | (reg & 0x3)));
}

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

long int dram_size (int board_type)
{
	/* No actual initialisation to do - done when setting up
	 * PICRs MCCRs ME/SARs etc in ram_init.S.
	 */

	register unsigned long i, msar1, mear1, memSize;

#if defined(CONFIG_SYS_MEMTEST)
	register unsigned long reg;

	printf ("Testing DRAM\n");

	/* write each mem addr with it's address */
	for (reg = CONFIG_SYS_MEMTEST_START; reg < CONFIG_SYS_MEMTEST_END; reg += 4)
		*reg = reg;

	for (reg = CONFIG_SYS_MEMTEST_START; reg < CONFIG_SYS_MEMTEST_END; reg += 4) {
		if (*reg != reg)
			return -1;
	}
#endif

	/*
	 * Since MPC106 memory controller chip has already been set to
	 * control all memory, just read and interpret its memory boundery register.
	 */
	memSize = 0;
	msar1 = mpc106_read_cfg_dword (MPC106_MSAR1);
	mear1 = mpc106_read_cfg_dword (MPC106_MEAR1);
	i = mpc106_read_cfg_dword (MPC106_MBER) & 0xf;

	do {
		if (i & 0x01)	/* is bank enabled ? */
			memSize += (mear1 & 0xff) - (msar1 & 0xff) + 1;
		msar1 >>= 8;
		mear1 >>= 8;
		i >>= 1;
	} while (i);

	return (memSize * 0x100000);
}

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

phys_size_t initdram (int board_type)
{
	return dram_size (board_type);
}

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

void after_reloc (ulong dest_addr)
{
	/*
	 * Jump to the main U-Boot board init code
	 */
	board_init_r ((gd_t *) gd, dest_addr);
}

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

/*
 * do_reset is done here because in this case it is board specific, since the
 * 7xx CPUs can only be reset by external HW (the RTC in this case).
 */
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#if defined(CONFIG_RTC_MK48T59)
	/* trigger watchdog immediately */
	rtc_set_watchdog (1, RTC_WD_RB_16TH);
#else
#error "You must define the macro CONFIG_RTC_MK48T59."
#endif
	return 0;
}

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

#if defined(CONFIG_WATCHDOG)
/*
 * Since the 7xx CPUs don't have an internal watchdog, this function is
 * board specific.  We use the RTC here.
 */
void watchdog_reset (void)
{
#if defined(CONFIG_RTC_MK48T59)
	/* we use a 32 sec watchdog timer */
	rtc_set_watchdog (8, RTC_WD_RB_4);
#else
#error "You must define the macro CONFIG_RTC_MK48T59."
#endif
}
#endif /* CONFIG_WATCHDOG */

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

#ifdef CONFIG_CONSOLE_EXTRA_INFO
extern GraphicDevice smi;

void video_get_info_str (int line_number, char *info)
{
	/* init video info strings for graphic console */
	switch (line_number) {
	case 1:
		sprintf (info, " MPC7xx V%d.%d at %ld / %ld MHz",
			 (get_pvr () >> 8) & 0xFF,
			 get_pvr () & 0xFF,
			 bab7xx_get_gclk_freq () / 1000000,
			 bab7xx_get_bus_freq () / 1000000);
		return;
	case 2:
		sprintf (info,
			 " ELTEC BAB7xx with %ld MB DRAM and %ld MB FLASH",
			 dram_size (0) / 0x100000, flash_init () / 0x100000);
		return;
	case 3:
		sprintf (info, " %s", smi.modeIdent);
		return;
	}

	/* no more info lines */
	*info = 0;
	return;
}
#endif

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

int board_eth_init(bd_t *bis)
{
	return pci_eth_init(bis);
}
