/*
 *  Copyright (C) 2005 Sandburst Corporation
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#include <config.h>
#include <common.h>
#include <command.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <spd_sdram.h>
#include <i2c.h>
#include "sb_common.h"

DECLARE_GLOBAL_DATA_PTR;

long int fixed_sdram (void);

/*************************************************************************
 *  metrobox_get_master
 *
 *  PRI_N - active low signal.	If the GPIO pin is low we are the master
 *
 ************************************************************************/
int sbcommon_get_master(void)
{
	ppc440_gpio_regs_t *gpio_regs;

	gpio_regs = (ppc440_gpio_regs_t *)CONFIG_SYS_GPIO_BASE;

	if (gpio_regs->in & SBCOMMON_GPIO_PRI_N) {
		return 0;
	}
	else {
		return 1;
	}
}

/*************************************************************************
 *  metrobox_secondary_present
 *
 *  Figure out if secondary/slave board is present
 *
 ************************************************************************/
int sbcommon_secondary_present(void)
{
	ppc440_gpio_regs_t *gpio_regs;

	gpio_regs = (ppc440_gpio_regs_t *)CONFIG_SYS_GPIO_BASE;

	if (gpio_regs->in & SBCOMMON_GPIO_SEC_PRES)
		return 0;
	else
		return 1;
}

/*************************************************************************
 *  sbcommon_get_serial_number
 *
 *  Retrieve the board serial number via the mac address in eeprom
 *
 ************************************************************************/
unsigned short sbcommon_get_serial_number(void)
{
	unsigned char buff[0x100];
	unsigned short sernum;

	/* Get the board serial number from eeprom */
	/* Initialize I2C */
	i2c_set_bus_num(0);

	/* Read 256 bytes in EEPROM */
	i2c_read (0x50, 0, 1, buff, 0x100);

	memcpy(&sernum, &buff[0xF4], 2);
	sernum /= 32;

	return (sernum);
}

/*************************************************************************
 *  sbcommon_fans
 *
 *  Spin up fans 2 & 3 to get some air moving.	OS will take care
 *  of the rest.  This is mostly a precaution...
 *
 *  Assumes i2c bus 1 is ready.
 *
 ************************************************************************/
void sbcommon_fans(void)
{
	/*
	 * Attempt to turn on 2 of the fans...
	 * Need to go through the bridge
	 */
	i2c_set_bus_num(1);
	puts ("FANS:  ");

	/* select fan4 through the bridge */
	i2c_reg_write(0x73, /* addr */
		      0x00, /* reg */
		      0x08); /* val = bus 4 */

	/* Turn on FAN 4 */
	i2c_reg_write(0x2e,
		      1,
		      0x80);

	i2c_reg_write(0x2e,
		      0,
		      0x19);

	/* Deselect bus 4 on the bridge */
	i2c_reg_write(0x73,
		      0x00,
		      0x00);

	/* select fan3 through the bridge */
	i2c_reg_write(0x73, /* addr */
		      0x00, /* reg */
		      0x04); /* val = bus 3 */

	/* Turn on FAN 3 */
	i2c_reg_write(0x2e,
		      1,
		      0x80);

	i2c_reg_write(0x2e,
		      0,
		      0x19);

	/* Deselect bus 3 on the bridge */
	i2c_reg_write(0x73,
		      0x00,
		      0x00);

	/* select fan2 through the bridge */
	i2c_reg_write(0x73, /* addr */
		      0x00, /* reg */
		      0x02); /* val = bus 4 */

	/* Turn on FAN 2 */
	i2c_reg_write(0x2e,
		      1,
		      0x80);

	i2c_reg_write(0x2e,
		      0,
		      0x19);

	/* Deselect bus 2 on the bridge */
	i2c_reg_write(0x73,
		      0x00,
		      0x00);

	/* select fan1 through the bridge */
	i2c_reg_write(0x73, /* addr */
		      0x00, /* reg */
		      0x01); /* val = bus 0 */

	/* Turn on FAN 1 */
	i2c_reg_write(0x2e,
		      1,
		      0x80);

	i2c_reg_write(0x2e,
		      0,
		      0x19);

	/* Deselect bus 1 on the bridge */
	i2c_reg_write(0x73,
		      0x00,
		      0x00);

	puts ("on\n");
	i2c_set_bus_num(0);

	return;

}

/*************************************************************************
 *  initdram
 *
 *  Initialize sdram
 *
 ************************************************************************/
phys_size_t initdram (int board_type)
{
	long dram_size = 0;

#if defined(CONFIG_SPD_EEPROM)
	dram_size = spd_sdram ();
#else
	dram_size = fixed_sdram ();
#endif
	return dram_size;
}


/*************************************************************************
 *  testdram
 *
 *
 ************************************************************************/
#if defined(CONFIG_SYS_DRAM_TEST)
int testdram (void)
{
	uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START;
	uint *pend = (uint *) CONFIG_SYS_MEMTEST_END;
	uint *p;

	printf("Testing SDRAM: ");
	for (p = pstart; p < pend; p++)
		*p = 0xaaaaaaaa;

	for (p = pstart; p < pend; p++) {
		if (*p != 0xaaaaaaaa) {
			printf ("SDRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	for (p = pstart; p < pend; p++)
		*p = 0x55555555;

	for (p = pstart; p < pend; p++) {
		if (*p != 0x55555555) {
			printf ("SDRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	printf("OK\n");
	return 0;
}
#endif

#if !defined(CONFIG_SPD_EEPROM)
/*************************************************************************
 *  fixed sdram init -- doesn't use serial presence detect.
 *
 *  Assumes:	128 MB, non-ECC, non-registered
 *		PLB @ 133 MHz
 *
 ************************************************************************/
long int fixed_sdram (void)
{
	uint reg;

	/*--------------------------------------------------------------------
	 * Setup some default
	 *------------------------------------------------------------------*/
	mtsdram (SDRAM0_UABBA, 0x00000000);	/* ubba=0 (default)		*/
	mtsdram (SDRAM0_SLIO, 0x00000000);		/* rdre=0 wrre=0 rarw=0		*/
	mtsdram (SDRAM0_DEVOPT, 0x00000000);	/* dll=0 ds=0 (normal)		*/
	mtsdram (SDRAM0_WDDCTR, 0x00000000);	/* wrcp=0 dcd=0			*/
	mtsdram (SDRAM0_CLKTR, 0x40000000);	/* clkp=1 (90 deg wr) dcdt=0	*/

	/*--------------------------------------------------------------------
	 * Setup for board-specific specific mem
	 *------------------------------------------------------------------*/
	/*
	 * Following for CAS Latency = 2.5 @ 133 MHz PLB
	 */
	mtsdram (SDRAM0_B0CR, 0x000a4001); /* SDBA=0x000 128MB, Mode 3, enabled */
	mtsdram (SDRAM0_TR0, 0x410a4012);	/* WR=2	 WD=1 CL=2.5 PA=3 CP=4 LD=2 */
	/* RA=10 RD=3			    */
	mtsdram (SDRAM0_TR1, 0x8080082f);	/* SS=T2 SL=STAGE 3 CD=1 CT=0x02f   */
	mtsdram (SDRAM0_RTR, 0x08200000);	/* Rate 15.625 ns @ 133 MHz PLB	    */
	mtsdram (SDRAM0_CFG1, 0x00000000); /* Self-refresh exit, disable PM    */
	udelay (400);			/* Delay 200 usecs (min)	    */

	/*--------------------------------------------------------------------
	 * Enable the controller, then wait for DCEN to complete
	 *------------------------------------------------------------------*/
	mtsdram (SDRAM0_CFG0, 0x86000000); /* DCEN=1, PMUD=1, 64-bit	    */
	for (;;) {
		mfsdram (SDRAM0_MCSTS, reg);
		if (reg & 0x80000000)
			break;
	}

	return (128 * 1024 * 1024);	/* 128 MB			    */
}
#endif	/* !defined(CONFIG_SPD_EEPROM) */

/*************************************************************************
 *  board_get_enetaddr
 *
 *  Get the ethernet MAC address for the management ethernet from the
 *  strap EEPROM.  Note that is the BASE address for the range of
 *  external ethernet MACs on the board.  The base + 31 is the actual
 *  mgmt mac address.
 *
 ************************************************************************/

void board_get_enetaddr(int macaddr_idx, uchar *enet)
{
	int i;
	unsigned short tmp;
	unsigned char buff[0x100], *cp;

	if (0 == macaddr_idx) {

		/* Initialize I2C */
		i2c_set_bus_num(0);

		/* Read 256 bytes in EEPROM */
		i2c_read (0x50, 0, 1, buff, 0x100);

		cp = &buff[0xF0];

		for (i = 0; i < 6; i++,cp++)
			enet[i] = *cp;

		memcpy(&tmp, &enet[4], 2);
		tmp += 31;
		memcpy(&enet[4], &tmp, 2);

	} else {
		enet[0] = 0x02;
		enet[1] = 0x00;
		enet[2] = 0x00;
		enet[3] = 0x00;
		enet[4] = 0x00;
		if (1 == sbcommon_get_master() ) {
			/* Master/Primary card */
			enet[5] = 0x01;
		} else {
			/* Slave/Secondary card */
			enet [5] = 0x02;
		}
	}

	return;
}

#ifdef CONFIG_POST
/*
 * Returns 1 if keys pressed to start the power-on long-running tests
 * Called from board_init_f().
 */
int post_hotkeys_pressed(void)
{

	return (ctrlc());
}
#endif
