/*
 * (C) Copyright 2001
 * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
 *
 * 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 "w7o.h"
#include <asm/processor.h>

#include "vpd.h"
#include "errors.h"
#include <watchdog.h>

unsigned long get_dram_size(void);

/*
 * Macros to transform values
 * into environment strings.
 */
#define XMK_STR(x)	#x
#define MK_STR(x)	XMK_STR(x)

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

int board_pre_init (void)
{
#if defined(CONFIG_W7OLMG)
    /*
     * Setup GPIO pins - reset devices.
     */
    out32(IBM405GP_GPIO0_ODR, 0x10000000);	/* one open drain pin */
    out32(IBM405GP_GPIO0_OR, 0x3E000000);	/* set output pins to default */
    out32(IBM405GP_GPIO0_TCR, 0x7f800000);	/* setup for output */

    /*
     * IRQ 0-15  405GP internally generated; active high; level sensitive
     * IRQ 16    405GP internally generated; active low; level sensitive
     * IRQ 17-24 RESERVED
     * IRQ 25 (EXT IRQ 0) XILINX; active low; level sensitive
     * IRQ 26 (EXT IRQ 1) PCI INT A; active low; level sensitive
     * IRQ 27 (EXT IRQ 2) PCI INT B; active low; level sensitive
     * IRQ 28 (EXT IRQ 3) SAM 2; active low; level sensitive
     * IRQ 29 (EXT IRQ 4) Battery Bad; active low; level sensitive
     * IRQ 30 (EXT IRQ 5) Level One PHY; active low; level sensitive
     * IRQ 31 (EXT IRQ 6) SAM 1; active high; level sensitive
     */
    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
    mtdcr(uicer, 0x00000000);			/* disable all ints */

    mtdcr(uiccr, 0x00000000);			/* set all to be non-critical*/
    mtdcr(uicpr, 0xFFFFFF80);			/* set int polarities */
    mtdcr(uictr, 0x10000000);			/* set int trigger levels */
    mtdcr(uicvcr, 0x00000001);			/* set vect base=0,
						   INT0 highest priority*/

    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */

#elif defined(CONFIG_W7OLMC)
    /*
     * Setup GPIO pins
     */
    out32(IBM405GP_GPIO0_ODR, 0x01800000);	/* XCV Done Open Drain */
    out32(IBM405GP_GPIO0_OR,  0x03800000);	/* set out pins to default */
    out32(IBM405GP_GPIO0_TCR, 0x66C00000);	/* setup for output */

    /*
     * IRQ 0-15  405GP internally generated; active high; level sensitive
     * IRQ 16    405GP internally generated; active low; level sensitive
     * IRQ 17-24 RESERVED
     * IRQ 25 (EXT IRQ 0) DBE 0; active low; level sensitive
     * IRQ 26 (EXT IRQ 1) DBE 1; active low; level sensitive
     * IRQ 27 (EXT IRQ 2) DBE 2; active low; level sensitive
     * IRQ 28 (EXT IRQ 3) DBE Common; active low; level sensitive
     * IRQ 29 (EXT IRQ 4) PCI; active low; level sensitive
     * IRQ 30 (EXT IRQ 5) RCMM Reset; active low; level sensitive
     * IRQ 31 (EXT IRQ 6) PHY; active high; level sensitive
     */
    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */
    mtdcr(uicer, 0x00000000);			/* disable all ints */

    mtdcr(uiccr, 0x00000000);			/* set all to be non-critical*/
    mtdcr(uicpr, 0xFFFFFF80);			/* set int polarities */
    mtdcr(uictr, 0x10000000);			/* set int trigger levels */
    mtdcr(uicvcr, 0x00000001);			/* set vect base=0,
						   INT0 highest priority*/

    mtdcr(uicsr, 0xFFFFFFFF);			/* clear all ints */

#else /* Unknown */
#    error "Unknown W7O board configuration"
#endif

    WATCHDOG_RESET();				/* Reset the watchdog */
    temp_uart_init();				/* init the uart for debug */
    WATCHDOG_RESET();				/* Reset the watchdog */
    test_led();					/* test the LEDs */
    test_sdram(get_dram_size());		/* test the dram */
    log_stat(ERR_POST1);			/* log status,post1 complete */
    return 0;
}


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

/*
 * Check Board Identity:
 */
int checkboard (void)
{
    VPD vpd;

    puts ("Board: ");

    /* VPD data present in I2C EEPROM */
    if (vpd_get_data(CFG_DEF_EEPROM_ADDR, &vpd) == 0) {
	/*
	 * Known board type.
	 */
	if (vpd.productId[0] &&
	    ((strncmp(vpd.productId, "GMM", 3) == 0) ||
	     (strncmp(vpd.productId, "CMM", 3) == 0))) {

	    /* Output board information on startup */
	    printf("\"%s\", revision '%c', serial# %ld, manufacturer %u\n",
		   vpd.productId, vpd.revisionId, vpd.serialNum, vpd.manuID);
	    return (0);
	}
    }

    puts ("### Unknown HW ID - assuming NOTHING\n");
    return (0);
}

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

long int initdram (int board_type)
{
    return get_dram_size();
}

unsigned long get_dram_size (void)
{
    int tmp, i, regs[4];
    int size = 0;

    /* Get bank Size registers */
    mtdcr(memcfga, mem_mb0cf);			/* get bank 0 config reg */
    regs[0] = mfdcr(memcfgd);

    mtdcr(memcfga, mem_mb1cf);			/* get bank 1 config reg */
    regs[1] = mfdcr(memcfgd);

    mtdcr(memcfga, mem_mb2cf);			/* get bank 2 config reg */
    regs[2] = mfdcr(memcfgd);

    mtdcr(memcfga, mem_mb3cf);			/* get bank 3 config reg */
    regs[3] = mfdcr(memcfgd);

    /* compute the size, add each bank if enabled */
    for(i = 0; i < 4; i++) {
	if (regs[i] & 0x0001) {			/* if enabled, */
	    tmp = ((regs[i] >> (31 - 14)) & 0x7); /* get size bits */
	    tmp = 0x400000 << tmp;		/* Size bits X 4MB = size */
	    size += tmp;
	}
    }

    return size;
}

int misc_init_f (void)
{
    return 0;
}

static void
w7o_env_init(VPD *vpd)
{
    /*
     * Read VPD
     */
    if (vpd_get_data(CFG_DEF_EEPROM_ADDR, vpd) != 0)
	return;

     /*
      * Known board type.
      */
    if (vpd->productId[0] &&
	((strncmp(vpd->productId, "GMM", 3) == 0) ||
	 (strncmp(vpd->productId, "CMM", 3) == 0))) {
	char buf[30];
	char *eth;
	unsigned char *serial = getenv("serial#");
	unsigned char *ethaddr = getenv("ethaddr");

	/* Set 'serial#' envvar if serial# isn't set */
	if (!serial) {
	    sprintf(buf, "%s-%ld", vpd->productId, vpd->serialNum);
	    setenv("serial#", buf);
	}

	/* Set 'ethaddr' envvar if 'ethaddr' envvar is the default */
	eth = vpd->ethAddrs[0];
	if (ethaddr && (strcmp(ethaddr, MK_STR(CONFIG_ETHADDR)) == 0)) {
	    /* Now setup ethaddr */
	    sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
		    eth[0], eth[1], eth[2], eth[3], eth[4], eth[5]);
	    setenv("ethaddr", buf);
	}
    }
} /* w7o_env_init() */


int misc_init_r (void)
{
    VPD vpd;					/* VPD information */

#if defined(CONFIG_W7OLMG)
    unsigned long greg;				/* GPIO Register */

    greg = in32(IBM405GP_GPIO0_OR);

    /*
     * XXX - Unreset devices - this should be moved into VxWorks driver code
     */
    greg |= 0x41800000L;			/* SAM, PHY, Galileo */

    out32(IBM405GP_GPIO0_OR, greg);		/* set output pins to default */
#endif /* CONFIG_W7OLMG */

    /*
     * Initialize W7O environment variables
     */
    w7o_env_init(&vpd);

    /*
     * Initialize the FPGA(s).
     */
    if (init_fpga() == 0)
	test_fpga((unsigned short *)CONFIG_FPGAS_BASE);

    /* More POST testing. */
    post2();

    /* Done with hardware initialization and POST. */
    log_stat(ERR_POSTOK);

    /* Call silly, fail safe boot init routine */
    init_fsboot();

	return (0);
}

