/*
 * bios32.c - PCI BIOS functions for m68k systems.
 *
 * Written by Wout Klaren.
 *
 * Based on the DEC Alpha bios32.c by Dave Rusling and David Mosberger.
 */

#include <linux/init.h>
#include <linux/kernel.h>

#if 0
# define DBG_DEVS(args)		printk args
#else
# define DBG_DEVS(args)
#endif

#ifdef CONFIG_PCI

/*
 * PCI support for Linux/m68k. Currently only the Hades is supported.
 *
 * The support for PCI bridges in the DEC Alpha version has
 * been removed in this version.
 */

#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/mm.h>

#include <asm/io.h>
#include <asm/pci.h>
#include <asm/uaccess.h>

#define KB		1024
#define MB		(1024*KB)
#define GB		(1024*MB)

#define MAJOR_REV	0
#define MINOR_REV	5

/*
 * Align VAL to ALIGN, which must be a power of two.
 */

#define ALIGN(val,align)	(((val) + ((align) - 1)) & ~((align) - 1))

/*
 * Offsets relative to the I/O and memory base addresses from where resources
 * are allocated.
 */

#define IO_ALLOC_OFFSET		0x00004000
#define MEM_ALLOC_OFFSET	0x04000000

/*
 * Declarations of hardware specific initialisation functions.
 */

extern struct pci_bus_info *init_hades_pci(void);

/*
 * Bus info structure of the PCI bus. A pointer to this structure is
 * put in the sysdata member of the pci_bus structure.
 */

static struct pci_bus_info *bus_info;

static int pci_modify = 1;		/* If set, layout the PCI bus ourself. */
static int skip_vga;			/* If set do not modify base addresses
					   of vga cards.*/
static int disable_pci_burst;		/* If set do not allow PCI bursts. */

static unsigned int io_base;
static unsigned int mem_base;

/*
 * static void disable_dev(struct pci_dev *dev)
 *
 * Disable PCI device DEV so that it does not respond to I/O or memory
 * accesses.
 *
 * Parameters:
 *
 * dev	- device to disable.
 */

static void __init disable_dev(struct pci_dev *dev)
{
	unsigned short cmd;

	if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
	     (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
		return;

	pci_read_config_word(dev, PCI_COMMAND, &cmd);

	cmd &= (~PCI_COMMAND_IO & ~PCI_COMMAND_MEMORY & ~PCI_COMMAND_MASTER);
	pci_write_config_word(dev, PCI_COMMAND, cmd);
}

/*
 * static void layout_dev(struct pci_dev *dev)
 *
 * Layout memory and I/O for a device.
 *
 * Parameters:
 *
 * device	- device to layout memory and I/O for.
 */

static void __init layout_dev(struct pci_dev *dev)
{
	unsigned short cmd;
	unsigned int base, mask, size, reg;
	unsigned int alignto;
	int i;

	/*
	 * Skip video cards if requested.
	 */

	if (((dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA) ||
	     (dev->class >> 8 == PCI_CLASS_DISPLAY_VGA) ||
	     (dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)) && skip_vga)
		return;

	pci_read_config_word(dev, PCI_COMMAND, &cmd);

	for (reg = PCI_BASE_ADDRESS_0, i = 0; reg <= PCI_BASE_ADDRESS_5; reg += 4, i++)
	{
		/*
		 * Figure out how much space and of what type this
		 * device wants.
		 */

		pci_write_config_dword(dev, reg, 0xffffffff);
		pci_read_config_dword(dev, reg, &base);

		if (!base)
		{
			/* this base-address register is unused */
			dev->resource[i].start = 0;
			dev->resource[i].end = 0;
			dev->resource[i].flags = 0;
			continue;
		}

		/*
		 * We've read the base address register back after
		 * writing all ones and so now we must decode it.
		 */

		if (base & PCI_BASE_ADDRESS_SPACE_IO)
		{
			/*
			 * I/O space base address register.
			 */

			cmd |= PCI_COMMAND_IO;

			base &= PCI_BASE_ADDRESS_IO_MASK;
			mask = (~base << 1) | 0x1;
			size = (mask & base) & 0xffffffff;

			/*
			 * Align to multiple of size of minimum base.
			 */

			alignto = max_t(unsigned int, 0x040, size);
			base = ALIGN(io_base, alignto);
			io_base = base + size;
			pci_write_config_dword(dev, reg, base | PCI_BASE_ADDRESS_SPACE_IO);

			dev->resource[i].start = base;
			dev->resource[i].end = dev->resource[i].start + size - 1;
			dev->resource[i].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;

			DBG_DEVS(("layout_dev: IO address: %lX\n", base));
		}
		else
		{
			unsigned int type;

			/*
			 * Memory space base address register.
			 */

			cmd |= PCI_COMMAND_MEMORY;
			type = base & PCI_BASE_ADDRESS_MEM_TYPE_MASK;
			base &= PCI_BASE_ADDRESS_MEM_MASK;
			mask = (~base << 1) | 0x1;
			size = (mask & base) & 0xffffffff;
			switch (type)
			{
			case PCI_BASE_ADDRESS_MEM_TYPE_32:
			case PCI_BASE_ADDRESS_MEM_TYPE_64:
				break;

			case PCI_BASE_ADDRESS_MEM_TYPE_1M:
				printk("bios32 WARNING: slot %d, function %d "
				       "requests memory below 1MB---don't "
				       "know how to do that.\n",
				       PCI_SLOT(dev->devfn),
				       PCI_FUNC(dev->devfn));
				continue;
			}

			/*
			 * Align to multiple of size of minimum base.
			 */

			alignto = max_t(unsigned int, 0x1000, size);
			base = ALIGN(mem_base, alignto);
			mem_base = base + size;
			pci_write_config_dword(dev, reg, base);

			dev->resource[i].start = base;
			dev->resource[i].end = dev->resource[i].start + size - 1;
			dev->resource[i].flags = IORESOURCE_MEM;

			if (type == PCI_BASE_ADDRESS_MEM_TYPE_64)
			{
				/*
				 * 64-bit address, set the highest 32 bits
				 * to zero.
				 */

				reg += 4;
				pci_write_config_dword(dev, reg, 0);

				i++;
				dev->resource[i].start = 0;
				dev->resource[i].end = 0;
				dev->resource[i].flags = 0;
			}
		}
	}

	/*
	 * Enable device:
	 */

	if (dev->class >> 8 == PCI_CLASS_NOT_DEFINED ||
	    dev->class >> 8 == PCI_CLASS_NOT_DEFINED_VGA ||
	    dev->class >> 8 == PCI_CLASS_DISPLAY_VGA ||
	    dev->class >> 8 == PCI_CLASS_DISPLAY_XGA)
	{
		/*
		 * All of these (may) have I/O scattered all around
		 * and may not use i/o-base address registers at all.
		 * So we just have to always enable I/O to these
		 * devices.
		 */
		cmd |= PCI_COMMAND_IO;
	}

	pci_write_config_word(dev, PCI_COMMAND, cmd | PCI_COMMAND_MASTER);

	pci_write_config_byte(dev, PCI_LATENCY_TIMER, (disable_pci_burst) ? 0 : 32);

	if (bus_info != NULL)
		bus_info->conf_device(dev);	/* Machine dependent configuration. */

	DBG_DEVS(("layout_dev: bus %d  slot 0x%x  VID 0x%x  DID 0x%x  class 0x%x\n",
		  dev->bus->number, PCI_SLOT(dev->devfn), dev->vendor, dev->device, dev->class));
}

/*
 * static void layout_bus(struct pci_bus *bus)
 *
 * Layout memory and I/O for all devices on the given bus.
 *
 * Parameters:
 *
 * bus	- bus.
 */

static void __init layout_bus(struct pci_bus *bus)
{
	unsigned int bio, bmem;
	struct pci_dev *dev;

	DBG_DEVS(("layout_bus: starting bus %d\n", bus->number));

	if (!bus->devices && !bus->children)
		return;

	/*
	 * Align the current bases on appropriate boundaries (4K for
	 * IO and 1MB for memory).
	 */

	bio = io_base = ALIGN(io_base, 4*KB);
	bmem = mem_base = ALIGN(mem_base, 1*MB);

	/*
	 * PCI devices might have been setup by a PCI BIOS emulation
	 * running under TOS. In these cases there is a
	 * window during which two devices may have an overlapping
	 * address range. To avoid this causing trouble, we first
	 * turn off the I/O and memory address decoders for all PCI
	 * devices.  They'll be re-enabled only once all address
	 * decoders are programmed consistently.
	 */

	DBG_DEVS(("layout_bus: disable_dev for bus %d\n", bus->number));

	for (dev = bus->devices; dev; dev = dev->sibling)
	{
		if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
		    (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
			disable_dev(dev);
	}

	/*
	 * Allocate space to each device:
	 */

	DBG_DEVS(("layout_bus: starting bus %d devices\n", bus->number));

	for (dev = bus->devices; dev; dev = dev->sibling)
	{
		if ((dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) ||
		    (dev->class >> 8 == PCI_CLASS_BRIDGE_PCMCIA))
			layout_dev(dev);
	}

	DBG_DEVS(("layout_bus: bus %d finished\n", bus->number));
}

/*
 * static void pcibios_fixup(void)
 *
 * Layout memory and I/O of all devices on the PCI bus if 'pci_modify' is
 * true. This might be necessary because not every m68k machine with a PCI
 * bus has a PCI BIOS. This function should be called right after
 * pci_scan_bus() in pcibios_init().
 */

static void __init pcibios_fixup(void)
{
	if (pci_modify)
	{
		/*
		 * Set base addresses for allocation of I/O and memory space.
		 */

		io_base = bus_info->io_space.start + IO_ALLOC_OFFSET;
		mem_base = bus_info->mem_space.start + MEM_ALLOC_OFFSET;

		/*
		 * Scan the tree, allocating PCI memory and I/O space.
		 */

		layout_bus(pci_bus_b(pci_root.next));
	}

	/*
	 * Fix interrupt assignments, etc.
	 */

	bus_info->fixup(pci_modify);
}

/*
 * static void pcibios_claim_resources(struct pci_bus *bus)
 *
 * Claim all resources that are assigned to devices on the given bus.
 *
 * Parameters:
 *
 * bus	- bus.
 */

static void __init pcibios_claim_resources(struct pci_bus *bus)
{
	struct pci_dev *dev;
	int i;

	while (bus)
	{
		for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
		{
			for (i = 0; i < PCI_NUM_RESOURCES; i++)
			{
				struct resource *r = &dev->resource[i];
				struct resource *pr;
				struct pci_bus_info *bus_info = (struct pci_bus_info *) dev->sysdata;

				if ((r->start == 0) || (r->parent != NULL))
					continue;
#if 1
				if (r->flags & IORESOURCE_IO)
					pr = &bus_info->io_space;
				else
					pr = &bus_info->mem_space;
#else
				if (r->flags & IORESOURCE_IO)
					pr = &ioport_resource;
				else
					pr = &iomem_resource;
#endif
				if (request_resource(pr, r) < 0)
				{
					printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", i, dev->name);
				}
			}
		}

		if (bus->children)
			pcibios_claim_resources(bus->children);

		bus = bus->next;
	}
}

/*
 * int pcibios_assign_resource(struct pci_dev *dev, int i)
 *
 * Assign a new address to a PCI resource.
 *
 * Parameters:
 *
 * dev	- device.
 * i	- resource.
 *
 * Result: 0 if successful.
 */

int __init pcibios_assign_resource(struct pci_dev *dev, int i)
{
	struct resource *r = &dev->resource[i];
	struct resource *pr = pci_find_parent_resource(dev, r);
	unsigned long size = r->end + 1;

	if (!pr)
		return -EINVAL;

	if (r->flags & IORESOURCE_IO)
	{
		if (size > 0x100)
			return -EFBIG;

		if (allocate_resource(pr, r, size, bus_info->io_space.start +
				      IO_ALLOC_OFFSET,  bus_info->io_space.end, 1024))
			return -EBUSY;
	}
	else
	{
		if (allocate_resource(pr, r, size, bus_info->mem_space.start +
				      MEM_ALLOC_OFFSET, bus_info->mem_space.end, size))
			return -EBUSY;
	}

	if (i < 6)
		pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i, r->start);

	return 0;
}

void __init pcibios_fixup_bus(struct pci_bus *bus)
{
	struct pci_dev *dev;
	void *sysdata;

	sysdata = (bus->parent) ? bus->parent->sysdata : bus->sysdata;

	for (dev = bus->devices; (dev != NULL); dev = dev->sibling)
		dev->sysdata = sysdata;
}

void __init pcibios_init(void)
{
	printk("Linux/m68k PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV);

	bus_info = NULL;

/* Hades code was:
	if (MACH_IS_HADES)
		bus_info = init_hades_pci();
*/

	if (bus_info != NULL)
	{
		printk("PCI: Probing PCI hardware\n");
		pci_scan_bus(0, bus_info->m68k_pci_ops, bus_info);
		pcibios_fixup();
		pcibios_claim_resources(pci_root);
	}
	else
		printk("PCI: No PCI bus detected\n");
}

char * __init pcibios_setup(char *str)
{
	if (!strcmp(str, "nomodify"))
	{
		pci_modify = 0;
		return NULL;
	}
	else if (!strcmp(str, "skipvga"))
	{
		skip_vga = 1;
		return NULL;
	}
	else if (!strcmp(str, "noburst"))
	{
		disable_pci_burst = 1;
		return NULL;
	}

	return str;
}
#endif /* CONFIG_PCI */
