/*
 * (C) Copyright 2008
 * Graeme Russ, graeme.russ@gmail.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 <asm/io.h>
#include <asm/ic/sc520.h>
#include <net.h>
#include <netdev.h>

#ifdef CONFIG_HW_WATCHDOG
#include <watchdog.h>
#endif

#include "hardware.h"

DECLARE_GLOBAL_DATA_PTR;

static void enet_timer_isr(void);
static void enet_toggle_run_led(void);
static void enet_setup_pars(void);

/*
 * Miscellaneous platform dependent initializations
 */
int board_early_init_f(void)
{
	u16 pio_out_cfg = 0x0000;

	/* Configure General Purpose Bus timing */
	writeb(CONFIG_SYS_SC520_GPCSRT, &sc520_mmcr->gpcsrt);
	writeb(CONFIG_SYS_SC520_GPCSPW, &sc520_mmcr->gpcspw);
	writeb(CONFIG_SYS_SC520_GPCSOFF, &sc520_mmcr->gpcsoff);
	writeb(CONFIG_SYS_SC520_GPRDW, &sc520_mmcr->gprdw);
	writeb(CONFIG_SYS_SC520_GPRDOFF, &sc520_mmcr->gprdoff);
	writeb(CONFIG_SYS_SC520_GPWRW, &sc520_mmcr->gpwrw);
	writeb(CONFIG_SYS_SC520_GPWROFF, &sc520_mmcr->gpwroff);

	/* Configure Programmable Input/Output Pins */
	writew(CONFIG_SYS_SC520_PIODIR15_0, &sc520_mmcr->piodir15_0);
	writew(CONFIG_SYS_SC520_PIODIR31_16, &sc520_mmcr->piodir31_16);
	writew(CONFIG_SYS_SC520_PIOPFS31_16, &sc520_mmcr->piopfs31_16);
	writew(CONFIG_SYS_SC520_PIOPFS15_0, &sc520_mmcr->piopfs15_0);
	writeb(CONFIG_SYS_SC520_CSPFS, &sc520_mmcr->cspfs);
	writeb(CONFIG_SYS_SC520_CLKSEL, &sc520_mmcr->clksel);

	/*
	 * Turn off top board
	 * Set StrataFlash chips to 16-bit width
	 * Set StrataFlash chips to normal (non reset/power down) mode
	 */
	pio_out_cfg |= CONFIG_SYS_ENET_TOP_BRD_PWR;
	pio_out_cfg |= CONFIG_SYS_ENET_SF_WIDTH;
	pio_out_cfg |= CONFIG_SYS_ENET_SF1_MODE;
	pio_out_cfg |= CONFIG_SYS_ENET_SF2_MODE;
	writew(pio_out_cfg, &sc520_mmcr->pioset15_0);

	/* Turn off auxiliary power output */
	writew(CONFIG_SYS_ENET_AUX_PWR, &sc520_mmcr->pioclr15_0);

	/* Clear FPGA program mode */
	writew(CONFIG_SYS_ENET_FPGA_PROG, &sc520_mmcr->pioset31_16);

	enet_setup_pars();

	/* Disable Watchdog */
	writew(0x3333, &sc520_mmcr->wdtmrctl);
	writew(0xcccc, &sc520_mmcr->wdtmrctl);
	writew(0x0000, &sc520_mmcr->wdtmrctl);

	/* Chip Select Configuration */
	writew(CONFIG_SYS_SC520_BOOTCS_CTRL, &sc520_mmcr->bootcsctl);
	writew(CONFIG_SYS_SC520_ROMCS1_CTRL, &sc520_mmcr->romcs1ctl);
	writew(CONFIG_SYS_SC520_ROMCS2_CTRL, &sc520_mmcr->romcs2ctl);

	writeb(CONFIG_SYS_SC520_ADDDECCTL, &sc520_mmcr->adddecctl);
	writeb(CONFIG_SYS_SC520_UART1CTL, &sc520_mmcr->uart1ctl);
	writeb(CONFIG_SYS_SC520_UART2CTL, &sc520_mmcr->uart2ctl);

	writeb(CONFIG_SYS_SC520_SYSARBCTL, &sc520_mmcr->sysarbctl);
	writew(CONFIG_SYS_SC520_SYSARBMENB, &sc520_mmcr->sysarbmenb);

	/* enable posted-writes */
	writeb(CONFIG_SYS_SC520_HBCTL, &sc520_mmcr->hbctl);

	return 0;
}

static void enet_setup_pars(void)
{
	/*
	 * PARs 11 and 12 are 2MB SRAM @ 0x19000000
	 *
	 * These are setup now because older version of U-Boot have them
	 * mapped to a different PAR which gets clobbered which prevents
	 * using SRAM for warm-booting a new image
	 */
	writel(CONFIG_SYS_SC520_SRAM1_PAR, &sc520_mmcr->par[11]);
	writel(CONFIG_SYS_SC520_SRAM2_PAR, &sc520_mmcr->par[12]);

	/* PARs 0 and 1 are Compact Flash slots (4kB each) */
	writel(CONFIG_SYS_SC520_CF1_PAR, &sc520_mmcr->par[0]);
	writel(CONFIG_SYS_SC520_CF2_PAR, &sc520_mmcr->par[1]);

	/* PAR 2 is used for Cache-As-RAM */

	/*
	 * PARs 5 through 8 are additional NS16550 UARTS
	 * 8 bytes each @ 0x013f8, 0x012f8, 0x011f8 and 0x010f8
	 */
	writel(CONFIG_SYS_SC520_UARTA_PAR, &sc520_mmcr->par[5]);
	writel(CONFIG_SYS_SC520_UARTB_PAR, &sc520_mmcr->par[6]);
	writel(CONFIG_SYS_SC520_UARTC_PAR, &sc520_mmcr->par[7]);
	writel(CONFIG_SYS_SC520_UARTD_PAR, &sc520_mmcr->par[8]);

	/* PARs 9 and 10 are 32MB StrataFlash @ 0x10000000 */
	writel(CONFIG_SYS_SC520_SF1_PAR, &sc520_mmcr->par[9]);
	writel(CONFIG_SYS_SC520_SF2_PAR, &sc520_mmcr->par[10]);

	/* PAR 13 is 4kB DPRAM @ 0x18100000 (implemented in FPGA) */
	writel(CONFIG_SYS_SC520_DPRAM_PAR, &sc520_mmcr->par[13]);

	/*
	 * PAR 14 is Low Level I/O (LEDs, Hex Switches etc)
	 * Already configured in board_init16 (eNET_start16.S)
	 *
	 * PAR 15 is Boot ROM
	 * Already configured in board_init16 (eNET_start16.S)
	 */
}


int board_early_init_r(void)
{
	/* CPU Speed to 100MHz */
	gd->cpu_clk = 100000000;

	/* Crystal is 33.000MHz */
	gd->bus_clk = 33000000;

	return 0;
}

void show_boot_progress(int val)
{
	uchar led_mask;

	led_mask = 0x00;

	if (val < 0)
		led_mask |= LED_ERR_BITMASK;

	led_mask |= (uchar)(val & 0x001f);
	outb(led_mask, LED_LATCH_ADDRESS);
}


int last_stage_init(void)
{
	int minor;
	int major;

	major = minor = 0;

	outb(0x00, LED_LATCH_ADDRESS);

	register_timer_isr(enet_timer_isr);

	printf("Serck Controls eNET\n");

	return 0;
}

ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
{
	if (banknum == 0) {	/* non-CFI boot flash */
		info->portwidth = FLASH_CFI_8BIT;
		info->chipwidth = FLASH_CFI_BY8;
		info->interface = FLASH_CFI_X8;
		return 1;
	} else {
		return 0;
	}
}

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

void setup_pcat_compatibility()
{
	/* disable global interrupt mode */
	writeb(0x40, &sc520_mmcr->picicr);

	/* set all irqs to edge */
	writeb(0x00, &sc520_mmcr->pic_mode[0]);
	writeb(0x00, &sc520_mmcr->pic_mode[1]);
	writeb(0x00, &sc520_mmcr->pic_mode[2]);

	/*
	 *  active low polarity on PIC interrupt pins,
	 *  active high polarity on all other irq pins
	 */
	writew(0x0000,&sc520_mmcr->intpinpol);

	/*
	 * PIT 0 -> IRQ0
	 * RTC -> IRQ8
	 * FP error -> IRQ13
	 * UART1 -> IRQ4
	 * UART2 -> IRQ3
	 */
	writeb(SC520_IRQ0, &sc520_mmcr->pit_int_map[0]);
	writeb(SC520_IRQ8, &sc520_mmcr->rtcmap);
	writeb(SC520_IRQ13, &sc520_mmcr->ferrmap);
	writeb(SC520_IRQ4, &sc520_mmcr->uart_int_map[0]);
	writeb(SC520_IRQ3, &sc520_mmcr->uart_int_map[1]);

	/* Disable all other interrupt sources */
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_tmr_int_map[0]);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_tmr_int_map[1]);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->gp_tmr_int_map[2]);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pit_int_map[1]);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->pit_int_map[2]);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->ssimap);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->wdtmap);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->wpvmap);
	writeb(SC520_IRQ_DISABLED, &sc520_mmcr->icemap);
}

void enet_timer_isr(void)
{
	static long enet_ticks = 0;

	enet_ticks++;

	/* Toggle Watchdog every 100ms */
	if ((enet_ticks % 100) == 0)
		hw_watchdog_reset();

	/* Toggle Run LED every 500ms */
	if ((enet_ticks % 500) == 0)
		enet_toggle_run_led();
}

void hw_watchdog_reset(void)
{
	/* Watchdog Reset must be atomic */
	long flag = disable_interrupts();

	if (sc520_mmcr->piodata15_0 & WATCHDOG_PIO_BIT)
		sc520_mmcr->pioclr15_0 = WATCHDOG_PIO_BIT;
	else
		sc520_mmcr->pioset15_0 = WATCHDOG_PIO_BIT;

	if (flag)
		enable_interrupts();
}

void enet_toggle_run_led(void)
{
	unsigned char leds_state= inb(LED_LATCH_ADDRESS);
	if (leds_state & LED_RUN_BITMASK)
		outb(leds_state &~ LED_RUN_BITMASK, LED_LATCH_ADDRESS);
	else
		outb(leds_state | LED_RUN_BITMASK, LED_LATCH_ADDRESS);
}
