/*
 * (C) Copyright 2002
 * Hyperion Entertainment, Hans-JoergF@hyperion-entertainment.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 <pci.h>
#include "memio.h"
#include "articiaS.h"

DECLARE_GLOBAL_DATA_PTR;

#undef ARTICIA_PCI_DEBUG

#ifdef  ARTICIA_PCI_DEBUG
#define PRINTF(fmt,args...)     printf (fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif

struct pci_controller articiaS_hose;

long irq_alloc(long wanted);

static pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index);
static int articiaS_init_vga(void);
static void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table);
unsigned char pci_irq_alloc(void);

extern void via_cfgfunc_via686(struct pci_controller * host, pci_dev_t dev, struct pci_config_table *table);
extern void via_cfgfunc_ide_init(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table);
extern void via_init_irq_routing(uint8 []);
extern void via_init_afterscan(void);

#define cfgfunc_via686      1
#define cfgfunc_dummy  2
#define cfgfunc_ide_init    3

static struct pci_config_table config_table[] =
{
    {
	0x1106, PCI_ANY_ID, PCI_CLASS_BRIDGE_ISA, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
	(void *)cfgfunc_via686, {0, 0, 0}
    },
    {
	0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,4,
	(void *)cfgfunc_dummy, {0,0,0}
    },
    {
	0x1106, 0x3068, PCI_ANY_ID, 0, 7, PCI_ANY_ID,
	(void *)cfgfunc_dummy, {0,0,0}
    },
    {
	0x1106, PCI_ANY_ID, PCI_ANY_ID, 0,7,1,
	(void *)cfgfunc_ide_init, {0,0,0}
    },
    {
	0,
    }
};


void pci_cfgfunc_dummy(struct pci_controller *host, pci_dev_t dev, struct pci_config_table *table)
{


}

unsigned long irq_penalties[16] =
{
    1000,    /* 0:timer */
    1000,    /* 1:keyboard */
    1000,    /* 2:cascade */
    50,      /* 3:serial (COM2) */
    50,      /* 4:serial (COM1) */
    4,       /* 5:USB2 */
    100,     /* 6:floppy */
    3,       /* 7:parallel */
    50,      /* 8:AC97/MC97 */
    0,       /* 9: */
    3,       /* 10:: */
    0,       /* 11: */
    3,       /* 12: USB1 */
    0,       /* 13: */
    100,     /* 14: ide0 */
    100,     /* 15: ide1 */
};


/*
 * The following defines a hard-coded interrupt mapping for the
 * know devices on the board.
 * If a device isn't found here, assumed to be a device that's
 * plugged into a PCI or AGP slot
 * NOTE: This table is machine dependant.
 */

struct pci_irq_fixup_table
{
    uint8   bus;             /* Bus number */
    uint8   device;          /* Device number */
    uint8   func;            /* Function number */
    uint8   interrupt;       /* Interrupt to use (0xff to disable) */
};

struct pci_irq_fixup_table fixuptab [] =
{
    { 0, 0, 0, 0xff},        /* Articia S host bridge */
    { 0, 1, 0, 0xff},        /* Articia S AGP bridge */
/*    { 0, 6, 0, 0x05},        /###* 3COM ethernet */
    { 0, 7, 0, 0xff},        /* VIA southbridge */
    { 0, 7, 1, 0x0e},        /* IDE controller in legacy mode */
/*    { 0, 7, 2, 0x05},        /###* First USB controller */
/*    { 0, 7, 3, 0x0c},        /###* Second USB controller (shares interrupt with ethernet) */
    { 0, 7, 4, 0xff},        /* ACPI Power Management */
/*    { 0, 7, 5, 0x08},        /###* AC97 */
/*    { 0, 7, 6, 0x08},        /###* MC97 */
    { 0xff, 0xff, 0xff, 0xff}
};


/*
 * This table maps IRQ's to PCI interrupts
 */

uint8 pci_intmap[4] = {0, 0, 0, 0};

/*
 * Map PCI slots to interrupt routings
 * This table lists the device number assigned to a card inserted
 * into the slot, along with a permutation for the slot's IRQ routing.
 * NOTE: This table is machine dependant.
 */

struct pci_slot_irq_routing
{
    uint8 bus;
    uint8 device;

    uint8 ints[4];
};

struct pci_slot_irq_routing amigaone_pci_routing[] =
{
    {0,  8,   {0, 1, 2, 3}},       /* Slot 1 (left of riser slot) */
    {0,  9,   {1, 2, 3, 0}},       /* Slot 2 (middle slot) */
    {0, 10,   {2, 3, 0, 1}},       /* Slot 3 (leftmost slot) */
    {1,  0,   {1, 0, 2, 3}},       /* AGP slot (only IRQA and IRQB) */
    {1,  1,   {1, 2, 3, 0}},       /* PCI slot on AGP bus */
    {0,  6,   {3, 3, 3, 3}},       /* On board ethernet */
    {0,  7,   {0, 1, 2, 3}},       /* Southbridge */
    {0xff, 0, {0, 0, 0, 0}}
};

void articiaS_pci_irq_init(void)
{
    char *s;

    s = getenv("pci_irqa");
    if (s)
	pci_intmap[0] = simple_strtoul (s, NULL, 10);
    else
	pci_intmap[0] = pci_irq_alloc();

    s = getenv("pci_irqb");
    if (s)
	pci_intmap[1] = simple_strtoul (s, NULL, 10);
    else
	pci_intmap[1] = pci_irq_alloc();

    s = getenv("pci_irqc");
    if (s)
	pci_intmap[2] = simple_strtoul (s, NULL, 10);
    else
	pci_intmap[2] = pci_irq_alloc();

    s = getenv("pci_irqd");
    if (s)
	pci_intmap[3] = simple_strtoul (s, NULL, 10);
    else
	pci_intmap[3] = pci_irq_alloc();
}


unsigned char pci_irq_alloc(void)
{
    int i;
    int interrupt = 10;
    unsigned long min_penalty = 1000;

    /* Search for the minimal penalty, favoring interrupts at the end */
    for (i = 0; i < 16; i++)
    {
	if (irq_penalties[i] <= min_penalty)
	{
	    interrupt = i;
	    min_penalty = irq_penalties[i];
	}
    }

    PRINTF("pci_irq_alloc: Minimal penalty is %ld for %d\n", min_penalty, interrupt);

    irq_penalties[interrupt]++;

    return interrupt;
}


void articiaS_pci_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
{
    int8 bus, device, func, pin, line;
    int i;

    bus = PCI_BUS(dev);
    device = PCI_DEV(dev);
    func = PCI_FUNC(dev);

    PRINTF("Fixup irq of %d:%d.%d\n", bus, device, func);

    /* Search for the device in the table */
    for (i = 0; fixuptab[i].bus != 0xff; i++)
    {
	if (bus == fixuptab[i].bus && device == fixuptab[i].device && func == fixuptab[i].func)
	{
	    /* If the device needs an interrupt, write it */
	    if (fixuptab[i].interrupt != 0xff)
	    {
		PRINTF("Assigning IRQ %d (fixed)\n", fixuptab[i].interrupt);
		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, fixuptab[i].interrupt);
	    }
	    else
	    {
		/* Otherwise, see if it wants an interrupt, and disable it if needed */
		pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
		if (pin)
		{
		    PRINTF("Disabling IRQ\n");
		    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 0xff);
		}
	    }

	    return;
	}
    }

    /* If we get here, we have another PCI device in a slot... find the appropriate IRQ */

    /* Find matching pin */
    pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
    pin--;

    /* Search for it's map */
    for (i = 0; amigaone_pci_routing[i].bus != 0xff; i++)
    {
	if (bus == amigaone_pci_routing[i].bus && device == amigaone_pci_routing[i].device)
	{
	    line = pci_intmap[amigaone_pci_routing[i].ints[pin]];
	    PRINTF("Assigning IRQ %d (pin %d)\n", line, pin);
	    pci_write_config_byte(dev, PCI_INTERRUPT_LINE, line);
	    return;
	}
    }

    PRINTF("Unkonwn PCI device found\n");
}

void articiaS_pci_init (void)
{
    int i;
    char *s;

    PRINTF("atriciaS_pci_init\n");

    /* Why aren't these relocated?? */
    for (i=0; config_table[i].config_device; i++)
    {
	switch((int)config_table[i].config_device)
	{
	case cfgfunc_via686:     config_table[i].config_device = via_cfgfunc_via686;      break;
	case cfgfunc_dummy:      config_table[i].config_device = pci_cfgfunc_dummy;       break;
	case cfgfunc_ide_init:   config_table[i].config_device = via_cfgfunc_ide_init;    break;
	default: PRINTF("Error: Unknown constant\n");
	}
    }

    articiaS_hose.first_busno = 0;
    articiaS_hose.last_busno = 0xff;
    articiaS_hose.config_table = config_table;
    articiaS_hose.fixup_irq = articiaS_pci_fixup_irq;

    articiaS_pci_irq_init();

    /* System memory */
    pci_set_region(articiaS_hose.regions + 0,
		   ARTICIAS_SYS_BUS,
		   ARTICIAS_SYS_PHYS,
		   ARTICIAS_SYS_MAXSIZE,
		   PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);

    /* PCI memory space */
    pci_set_region(articiaS_hose.regions + 1,
		   ARTICIAS_PCI_BUS,
		   ARTICIAS_PCI_PHYS,
		   ARTICIAS_PCI_MAXSIZE,
		   PCI_REGION_MEM);

    /* PCI io space */
    pci_set_region(articiaS_hose.regions + 2,
		   ARTICIAS_PCIIO_BUS,
		   ARTICIAS_PCIIO_PHYS,
		   ARTICIAS_PCIIO_MAXSIZE,
		   PCI_REGION_IO);

    /* PCI/ISA io space */
    pci_set_region(articiaS_hose.regions + 3,
		   ARTICIAS_ISAIO_BUS,
		   ARTICIAS_ISAIO_PHYS,
		   ARTICIAS_ISAIO_MAXSIZE,
		   PCI_REGION_IO);


    articiaS_hose.region_count = 4;

    pci_setup_indirect(&articiaS_hose, ARTICIAS_PCI_CFGADDR, ARTICIAS_PCI_CFGDATA);
    PRINTF("Registering articia hose...\n");
    pci_register_hose(&articiaS_hose);
    PRINTF("Enabling AGP...\n");
    pci_write_config_byte(PCI_BDF(0,0,0), 0x58, 0x01);
    PRINTF("Scanning bus...\n");
    articiaS_hose.last_busno = pci_hose_scan(&articiaS_hose);

    via_init_irq_routing(pci_intmap);

    PRINTF("After-Scan results:\n");
    PRINTF("Bus range: %d - %d\n", articiaS_hose.first_busno , articiaS_hose.last_busno);

    via_init_afterscan();

    pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF);

    s = getenv("as_irq");
    if (s)
    {
	pci_write_config_byte(PCI_BDF(0,0,0), PCI_INTERRUPT_LINE, simple_strtoul (s, NULL, 10));
    }

    s = getenv("x86_run_bios");
    if (!s || (s && strcmp(s, "on")==0))
    {
	if (articiaS_init_vga() == -1)
	{
	    /* If the VGA didn't init and we have stdout set to VGA, reset to serial */
/*	    s = getenv("stdout"); */
/*	    if (s && strcmp(s, "vga") == 0) */
/*	    { */
/*		setenv("stdout", "serial"); */
/*	    } */
	}
    }
    pci_write_config_byte(PCI_BDF(0,1,0), PCI_INTERRUPT_LINE, 0xFF);

}

pci_dev_t pci_hose_find_class(struct pci_controller *hose, int bus, short find_class, int index)
{
    unsigned int sub_bus, found_multi=0;
    unsigned short vendor, class;
    unsigned char header_type;
    pci_dev_t dev;
    u8 c1, c2;

    sub_bus = bus;

    for (dev =  PCI_BDF(bus,0,0);
	 dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
	 dev += PCI_BDF(0,0,1))
    {
	if ( dev == PCI_BDF(hose->first_busno,0,0) )
	    continue;

	if (PCI_FUNC(dev) && !found_multi)
	    continue;

	pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);

	pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);

	if (vendor != 0xffff && vendor != 0x0000)
	{

	    if (!PCI_FUNC(dev))
		found_multi = header_type & 0x80;
	    pci_hose_read_config_byte(hose, dev, 0x0B, &c1);
	    pci_hose_read_config_byte(hose, dev, 0x0A, &c2);
	    class = c1<<8 | c2;
	    /*printf("At %02x:%02x:%02x: class %x\n", */
	    /*	   PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev), class); */
	    if (class == find_class)
	    {
		if (index == 0)
		    return dev;
		else index--;
	    }
	}
    }

    return ~0;
}


/*
 * For a given bus number, find the bridge on this hose that provides this
 * bus number. The function scans for bridges and peeks config space offset
 * 0x19 (PCI_SECONDARY_BUS).
 */
pci_dev_t pci_find_bridge_for_bus(struct pci_controller *hose, int busnr)
{
    pci_dev_t dev;
    int bus;
    unsigned int found_multi=0;
    unsigned char header_type;
    unsigned short vendor;
    unsigned char secondary_bus;

    if (hose == NULL) hose = &articiaS_hose;

    if (busnr < hose->first_busno || busnr > hose->last_busno) return PCI_ANY_ID; /* Not in range */

    /*
     * The bridge must be on a lower bus number
     */
    for (bus = hose->first_busno; bus < busnr; bus++)
    {
	for (dev =  PCI_BDF(bus,0,0);
	     dev <  PCI_BDF(bus,PCI_MAX_PCI_DEVICES-1,PCI_MAX_PCI_FUNCTIONS-1);
	     dev += PCI_BDF(0,0,1))
	{
	    if ( dev == PCI_BDF(hose->first_busno,0,0) )
		continue;

	    if (PCI_FUNC(dev) && !found_multi)
		continue;

	    pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);

	    pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);

	    if (vendor != 0xffff && vendor != 0x0000)
	    {

		if (!PCI_FUNC(dev))
		    found_multi = header_type & 0x80;
		if (header_type == 1) /* Bridge device header */
		{
		    pci_hose_read_config_byte(hose, dev, PCI_SECONDARY_BUS, &secondary_bus);
		    if ((int)secondary_bus == busnr) return dev;
		}

	    }
	}
    }
    return PCI_ANY_ID;
}

static short classes[] =
{
    PCI_CLASS_DISPLAY_VGA,
    PCI_CLASS_DISPLAY_XGA,
    PCI_CLASS_DISPLAY_3D,
    PCI_CLASS_DISPLAY_OTHER,
    ~0
};

extern int execute_bios(pci_dev_t gr_dev, void *);

pci_dev_t video_dev;

int articiaS_init_vga (void)
{
    extern void shutdown_bios(void);
    pci_dev_t dev = ~0;
    int busnr = 0;
    int classnr = 0;

    video_dev = PCI_ANY_ID;

    printf("VGA:   ");

    PRINTF("Trying to initialize x86 VGA Card(s)\n");

    while (dev == ~0)
    {
	PRINTF("Searching for class 0x%x on bus %d\n", classes[classnr], busnr);
	/* Find the first of this class on this bus */
	dev = pci_hose_find_class(&articiaS_hose, busnr, classes[classnr], 0);
	if (dev != ~0)
	{
	    PRINTF("Found VGA Card at %02x:%02x:%02x\n", PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
	    break;
	}
	busnr++;
	if (busnr > articiaS_hose.last_busno)
	{
	    busnr = 0;
	    classnr ++;
	    if (classes[classnr] == ~0)
	    {
		printf("NOT PRESENT\n");
		return -1;
	    }
	}
    }

    /*
     * If we get here we have found the first graphics card.
     * If the bus number is not 0, then it is probably behind a bridge, and the
     * bridge needs to be told to forward VGA access.
     */

    if (PCI_BUS(dev) != 0)
    {
	pci_dev_t bridge;
	PRINTF("Behind bridge, looking for bridge\n");
	bridge = pci_find_bridge_for_bus(&articiaS_hose, PCI_BUS(dev));
	if (dev != PCI_ANY_ID)
	{
	    unsigned char agp_control_0;
	    PRINTF("Got the bridge at %02x:%02x:%02x\n",
		   PCI_BUS(bridge), PCI_DEV(bridge), PCI_FUNC(bridge));
	    pci_hose_read_config_byte(&articiaS_hose, bridge, 0x3E, &agp_control_0);
	    agp_control_0 |= 0x18;
	    pci_hose_write_config_byte(&articiaS_hose, bridge, 0x3E, agp_control_0);
	    PRINTF("Configured for VGA forwarding\n");
	}
    }

    /*
     * Now try to run the bios
     */
    PRINTF("Trying to run bios now\n");
    if (execute_bios(dev, gd->relocaddr))
    {
	printf("OK\n");
	video_dev = dev;
    }
    else
    {
	printf("ERROR\n");
    }

    PRINTF("Done scanning.\n");

    shutdown_bios();

    if (dev == PCI_ANY_ID) return -1;
    else return 0;

}
