/*
 * (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_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;

}
