/*
 * (C) Copyright 2002 Wolfgang Grandegger <wg@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 <common.h>
#include <mpc824x.h>
#include <asm/io.h>
#include <pci.h>

#include "pn62.h"

typedef struct {
    pci_dev_t    devno;
    volatile u32 *csr;

} i2155x_t;

static i2155x_t i2155x = { 0, NULL };

static struct pci_device_id i2155x_ids[] = {
    { 0x1011, 0x0046 },		/* i21554 */
    { 0x8086, 0xb555 }		/* i21555 */
};

int i2155x_init(void)
{
    pci_dev_t devno;
    u32 val;
    int i;

    /*
     * Find the Intel bridge.
     */
    if ((devno = pci_find_devices(i2155x_ids, 0)) < 0) {
	printf("Error: Intel bridge 2155x not found!\n");
	return -1;
    }
    i2155x.devno = devno;

    /*
     * Get auto-configured base address for CSR access.
     */
    pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &val);
    if (val & PCI_BASE_ADDRESS_SPACE_IO) {
	val &= PCI_BASE_ADDRESS_IO_MASK;
	i2155x.csr = (volatile u32 *)(_IO_BASE + val);
    } else {
	val &= PCI_BASE_ADDRESS_MEM_MASK;
	i2155x.csr =  (volatile u32 *)val;
    }

    /*
     * Translate downstream memory 2 (bar3) to base of shared memory.
     */
    i2155x_set_bar_base(3, PN62_SMEM_DEFAULT);

    /*
     * Enable memory space, I/O space and bus master bits
     * in both Primary and Secondary command registers.
     */
    val = PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER|PCI_COMMAND_IO;
    pci_write_config_word(devno, 0x44, val);
    pci_write_config_word(devno, 0x04, val);

    /*
     * Clear scratchpad registers.
     */
    for (i = 0; i < (I2155X_SCRAPAD_MAX - 1); i++) {
	i2155x_write_scrapad(i, 0x0);
    }

    /*
     * Set interrupt line for Linux.
     */
    pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 3);

    return 0;
}

/*
 * Access the Scratchpad registers 0..7 of the Intel bridge.
 */
void i2155x_write_scrapad(int idx, u32 val)
{
    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
	out_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx, val);
    else
	printf("i2155x_write_scrapad: invalid index\n");
}

u32 i2155x_read_scrapad(int idx)
{
    if (idx >= 0 && idx < I2155X_SCRAPAD_MAX)
	return in_le32(i2155x.csr + (I2155X_SCRAPAD_ADDR/4) + idx);
    else
	printf("i2155x_read_scrapad: invalid index\n");
    return -1;
}

void i2155x_set_bar_base(int bar, u32 base)
{
    if (bar >= 2 && bar <= 4) {
	pci_write_config_dword(i2155x.devno,
			       I2155X_BAR2_BASE + (bar - 2) * 4,
			       base);
    }
}

/*
 * Read Vital Product Data (VPD) from the Serial EPROM attached
 * to the Intel bridge.
 */
int i2155x_read_vpd(int offset, int size, unsigned char *data)
{
    int i, n;
    u16 val16;

    for (i = 0; i < size; i++) {
	pci_write_config_word(i2155x.devno, I2155X_VPD_ADDR,
			      offset + i - I2155X_VPD_START);
	for (n = 10000; n > 0; n--) {
	    pci_read_config_word(i2155x.devno, I2155X_VPD_ADDR, &val16);
	    if ((val16 & 0x8000) != 0) /* wait for completion */
		break;
	    udelay(100);
	}
	if (n == 0) {
	    printf("i2155x_read_vpd: TIMEOUT\n");
	    return -1;
	}

	pci_read_config_byte(i2155x.devno, I2155X_VPD_DATA, &data[i]);
    }

    return i;
}

static struct pci_device_id am79c95x_ids [] = {
	{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE },
	{ }
};


/*
 * Initialize the AMD ethernet controllers.
 */
int am79c95x_init(void)
{
    pci_dev_t devno;
    int i;

    /*
     * Set interrupt line for Linux.
     */
    for (i = 0; i < 2; i++) {
	if ((devno = pci_find_devices(am79c95x_ids, i)) < 0)
	    break;
	pci_write_config_byte(devno, PCI_INTERRUPT_LINE, 2+i);
    }
    if (i < 2)
	printf("Error: Only %d AMD Ethernet Controller found!\n", i);

    return 0;
}


void set_led(unsigned int number, unsigned int function)
{
    volatile u8 *addr;

    if ((number >= 0) && (number < PN62_LED_MAX) &&
	(function >= 0) && (function <= LED_LAST_FUNCTION)) {
	addr = (volatile u8 *)(PN62_LED_BASE + number * 8);
	out_8(addr, function&0xff);
    }
}

/*
 * Show fatal error indicated by Kinght Rider(tm) effect
 * in LEDS 0-7. LEDS 8-11 contain 4 bit error code.
 * Note: this function will not terminate.
 */
void fatal_error(unsigned int error_code)
{
    int i, d;

    for (i = 0; i < 12; i++) {
	set_led(i, LED_0);
    }

    /*
     * Write error code.
     */
    set_led(8,  (error_code & 0x01) ? LED_1 : LED_0);
    set_led(9,  (error_code & 0x02) ? LED_1 : LED_0);
    set_led(10, (error_code & 0x04) ? LED_1 : LED_0);
    set_led(11, (error_code & 0x08) ? LED_1 : LED_0);

    /*
     * Yay - Knight Rider effect!
     */
    while(1) {
	unsigned int delay = 2000;

	for (i = 0; i < 8; i++) {
	    set_led(i, LED_1);
	    for (d = 0; d < delay; d++);
	    set_led(i, LED_0);
	}

	for (i = 7; i > 0; i--) {
	    set_led(i, LED_1);
	    for (d = 0; d < delay; d++);
	    set_led(i, LED_0);
	}
    }
}
