/*
 * Copyright 2003 PMC-Sierra
 * Author: Manish Lachwani (lachwani@pmc-sierra.com)
 *
 *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <asm/pci.h>
#include <asm/io.h>

#include <linux/init.h>
#include <asm/titan_dep.h>

#ifdef CONFIG_HYPERTRANSPORT


/*
 * This function check if the Hypertransport Link Initialization completed. If
 * it did, then proceed further with scanning bus #2
 */
static __inline__ int check_titan_htlink(void)
{
        u32 val;

        val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG);
        if (val & 0x00000020)
                /* HT Link Initialization completed */
                return 1;
        else
                return 0;
}

static int titan_ht_config_read_dword(struct pci_dev *device,
                                             int offset, u32* val)
{
        int dev, bus, func;
        uint32_t address_reg, data_reg;
        uint32_t address;

        bus = device->bus->number;
        dev = PCI_SLOT(device->devfn);
        func = PCI_FUNC(device->devfn);

	/* XXX Need to change the Bus # */
        if (bus > 2)
                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
                                                        0x80000000 | 0x1;
        else
                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;

        address_reg = RM9000x2_OCD_HTCFGA;
        data_reg =  RM9000x2_OCD_HTCFGD;

        RM9K_WRITE(address_reg, address);
        RM9K_READ(data_reg, val);

        return PCIBIOS_SUCCESSFUL;
}


static int titan_ht_config_read_word(struct pci_dev *device,
                                             int offset, u16* val)
{
        int dev, bus, func;
        uint32_t address_reg, data_reg;
        uint32_t address;

        bus = device->bus->number;
        dev = PCI_SLOT(device->devfn);
        func = PCI_FUNC(device->devfn);

	/* XXX Need to change the Bus # */
        if (bus > 2)
                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
                                                0x80000000 | 0x1;
        else
                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;

        address_reg = RM9000x2_OCD_HTCFGA;
        data_reg =  RM9000x2_OCD_HTCFGD;

        if ((offset & 0x3) == 0)
                offset = 0x2;
        else
                offset = 0x0;

        RM9K_WRITE(address_reg, address);
        RM9K_READ_16(data_reg + offset, val);

        return PCIBIOS_SUCCESSFUL;
}


u32 longswap(unsigned long l)
{
        unsigned char b1, b2, b3, b4;

        b1 = l&255;
        b2 = (l>>8)&255;
        b3 = (l>>16)&255;
        b4 = (l>>24)&255;

        return ((b1<<24) + (b2<<16) + (b3<<8) + b4);
}


static int titan_ht_config_read_byte(struct pci_dev *device,
                                             int offset, u8* val)
{
        int dev, bus, func;
        uint32_t address_reg, data_reg;
        uint32_t address;
        int offset1;

        bus = device->bus->number;
        dev = PCI_SLOT(device->devfn);
        func = PCI_FUNC(device->devfn);

	/* XXX Need to change the Bus # */
        if (bus > 2)
                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
                                                        0x80000000 | 0x1;
        else
                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;

        address_reg = RM9000x2_OCD_HTCFGA;
        data_reg =  RM9000x2_OCD_HTCFGD;

        RM9K_WRITE(address_reg, address);

        if ((offset & 0x3) == 0) {
                offset1 = 0x3;
        }
        if ((offset & 0x3) == 1) {
                offset1 = 0x2;
        }
        if ((offset & 0x3) == 2) {
                offset1 = 0x1;
        }
        if ((offset & 0x3) == 3) {
                offset1 = 0x0;
        }
        RM9K_READ_8(data_reg + offset1, val);

        return PCIBIOS_SUCCESSFUL;
}


static int titan_ht_config_write_dword(struct pci_dev *device,
                                             int offset, u8 val)
{
        int dev, bus, func;
        uint32_t address_reg, data_reg;
        uint32_t address;

        bus = device->bus->number;
        dev = PCI_SLOT(device->devfn);
        func = PCI_FUNC(device->devfn);

	/* XXX Need to change the Bus # */
        if (bus > 2)
                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
                                                        0x80000000 | 0x1;
        else
              address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;

        address_reg = RM9000x2_OCD_HTCFGA;
        data_reg =  RM9000x2_OCD_HTCFGD;

        RM9K_WRITE(address_reg, address);
        RM9K_WRITE(data_reg, val);

        return PCIBIOS_SUCCESSFUL;
}

static int titan_ht_config_write_word(struct pci_dev *device,
                                             int offset, u8 val)
{
        int dev, bus, func;
        uint32_t address_reg, data_reg;
        uint32_t address;

        bus = device->bus->number;
        dev = PCI_SLOT(device->devfn);
        func = PCI_FUNC(device->devfn);

	/* XXX Need to change the Bus # */
        if (bus > 2)
                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
                                0x80000000 | 0x1;
        else
                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;

        address_reg = RM9000x2_OCD_HTCFGA;
        data_reg =  RM9000x2_OCD_HTCFGD;

        if ((offset & 0x3) == 0)
                offset = 0x2;
        else
                offset = 0x0;

        RM9K_WRITE(address_reg, address);
        RM9K_WRITE_16(data_reg + offset, val);

        return PCIBIOS_SUCCESSFUL;
}

static int titan_ht_config_write_byte(struct pci_dev *device,
                                             int offset, u8 val)
{
        int dev, bus, func;
        uint32_t address_reg, data_reg;
        uint32_t address;
        int offset1;

        bus = device->bus->number;
        dev = PCI_SLOT(device->devfn);
        func = PCI_FUNC(device->devfn);

	/* XXX Need to change the Bus # */
        if (bus > 2)
                address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
                                0x80000000 | 0x1;
        else
                address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;

        address_reg = RM9000x2_OCD_HTCFGA;
        data_reg =  RM9000x2_OCD_HTCFGD;

        RM9K_WRITE(address_reg, address);

        if ((offset & 0x3) == 0) {
             offset1 = 0x3;
        }
        if ((offset & 0x3) == 1) {
             offset1 = 0x2;
        }
        if ((offset & 0x3) == 2) {
             offset1 = 0x1;
        }
        if ((offset & 0x3) == 3) {
            offset1 = 0x0;
        }

        RM9K_WRITE_8(data_reg + offset1, val);
        return PCIBIOS_SUCCESSFUL;
}


static void titan_pcibios_set_master(struct pci_dev *dev)
{
        u16 cmd;
        int bus = dev->bus->number;

	if (check_titan_htlink())
            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);

	cmd |= PCI_COMMAND_MASTER;

	if (check_titan_htlink())
            titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
}


int pcibios_enable_resources(struct pci_dev *dev)
{
        u16 cmd, old_cmd;
        u8 tmp1;
        int idx;
        struct resource *r;
        int bus = dev->bus->number;

	if (check_titan_htlink())
            titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);

	old_cmd = cmd;
        for (idx = 0; idx < 6; idx++) {
                r = &dev->resource[idx];
                if (!r->start && r->end) {
                        printk(KERN_ERR
                               "PCI: Device %s not available because of "
                               "resource collisions\n", pci_name(dev));
                        return -EINVAL;
                }
                if (r->flags & IORESOURCE_IO)
                        cmd |= PCI_COMMAND_IO;
                if (r->flags & IORESOURCE_MEM)
                        cmd |= PCI_COMMAND_MEMORY;
        }
        if (cmd != old_cmd) {
		if (check_titan_htlink())
                   titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
	}

	if (check_titan_htlink())
		titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);

	if (tmp1 != 8) {
                printk(KERN_WARNING "PCI setting cache line size to 8 from "
                       "%d\n", tmp1);
	}

	if (check_titan_htlink())
		titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8);

	if (check_titan_htlink())
		titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1);

	if (tmp1 < 32 || tmp1 == 0xff) {
                printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
                       tmp1);
	}

	if (check_titan_htlink())
		titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32);

	return 0;
}


int pcibios_enable_device(struct pci_dev *dev, int mask)
{
        return pcibios_enable_resources(dev);
}



void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
                             struct resource *res, int resource)
{
        u32 new, check;
        int reg;

        return;

        new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
        if (resource < 6) {
                reg = PCI_BASE_ADDRESS_0 + 4 * resource;
        } else if (resource == PCI_ROM_RESOURCE) {
		res->flags |= IORESOURCE_ROM_ENABLE;
                reg = dev->rom_base_reg;
        } else {
                /*
                 * Somebody might have asked allocation of a non-standard
                 * resource
                 */
                return;
        }

        pci_write_config_dword(dev, reg, new);
        pci_read_config_dword(dev, reg, &check);
        if ((new ^ check) &
            ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
             PCI_BASE_ADDRESS_MEM_MASK)) {
                printk(KERN_ERR "PCI: Error while updating region "
                       "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
                       new, check);
        }
}


void pcibios_align_resource(void *data, struct resource *res,
                            resource_size_t size, resource_size_t align)
{
        struct pci_dev *dev = data;

        if (res->flags & IORESOURCE_IO) {
                resource_size_t start = res->start;

                /* We need to avoid collisions with `mirrored' VGA ports
                   and other strange ISA hardware, so we always want the
                   addresses kilobyte aligned.  */
                if (size > 0x100) {
                        printk(KERN_ERR "PCI: I/O Region %s/%d too large"
                               " (%ld bytes)\n", pci_name(dev),
                                dev->resource - res, size);
                }

                start = (start + 1024 - 1) & ~(1024 - 1);
                res->start = start;
        }
}

struct pci_ops titan_pci_ops = {
        titan_ht_config_read_byte,
        titan_ht_config_read_word,
        titan_ht_config_read_dword,
        titan_ht_config_write_byte,
        titan_ht_config_write_word,
        titan_ht_config_write_dword
};

void __init pcibios_fixup_bus(struct pci_bus *c)
{
        titan_ht_pcibios_fixup_bus(c);
}

void __init pcibios_init(void)
{

        /* Reset PCI I/O and PCI MEM values */
	/* XXX Need to add the proper values here */
        ioport_resource.start = 0xe0000000;
        ioport_resource.end   = 0xe0000000 + 0x20000000 - 1;
        iomem_resource.start  = 0xc0000000;
        iomem_resource.end    = 0xc0000000 + 0x20000000 - 1;

	/* XXX Need to add bus values */
        pci_scan_bus(2, &titan_pci_ops, NULL);
        pci_scan_bus(3, &titan_pci_ops, NULL);
}

/*
 * for parsing "pci=" kernel boot arguments.
 */
char *pcibios_setup(char *str)
{
        printk(KERN_INFO "rr: pcibios_setup\n");
        /* Nothing to do for now.  */

        return str;
}

unsigned __init int pcibios_assign_all_busses(void)
{
        /* We want to use the PCI bus detection done by PMON */
        return 0;
}

#endif /* CONFIG_HYPERTRANSPORT */
