/*
 * Support for PCI on Celleb platform.
 *
 * (C) Copyright 2006-2007 TOSHIBA CORPORATION
 *
 * This code is based on arch/powerpc/kernel/rtas_pci.c:
 *  Copyright (C) 2001 Dave Engebretsen, IBM Corporation
 *  Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#undef DEBUG

#include <linux/kernel.h>
#include <linux/threads.h>
#include <linux/pci.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/pci_regs.h>
#include <linux/of.h>
#include <linux/of_device.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>

#include "io-workarounds.h"
#include "celleb_pci.h"

#define MAX_PCI_DEVICES    32
#define MAX_PCI_FUNCTIONS   8
#define MAX_PCI_BASE_ADDRS  3 /* use 64 bit address */

/* definition for fake pci configuration area for GbE, .... ,and etc. */

struct celleb_pci_resource {
	struct resource r[MAX_PCI_BASE_ADDRS];
};

struct celleb_pci_private {
	unsigned char *fake_config[MAX_PCI_DEVICES][MAX_PCI_FUNCTIONS];
	struct celleb_pci_resource *res[MAX_PCI_DEVICES][MAX_PCI_FUNCTIONS];
};

static inline u8 celleb_fake_config_readb(void *addr)
{
	u8 *p = addr;
	return *p;
}

static inline u16 celleb_fake_config_readw(void *addr)
{
	__le16 *p = addr;
	return le16_to_cpu(*p);
}

static inline u32 celleb_fake_config_readl(void *addr)
{
	__le32 *p = addr;
	return le32_to_cpu(*p);
}

static inline void celleb_fake_config_writeb(u32 val, void *addr)
{
	u8 *p = addr;
	*p = val;
}

static inline void celleb_fake_config_writew(u32 val, void *addr)
{
	__le16 val16;
	__le16 *p = addr;
	val16 = cpu_to_le16(val);
	*p = val16;
}

static inline void celleb_fake_config_writel(u32 val, void *addr)
{
	__le32 val32;
	__le32 *p = addr;
	val32 = cpu_to_le32(val);
	*p = val32;
}

static unsigned char *get_fake_config_start(struct pci_controller *hose,
					    int devno, int fn)
{
	struct celleb_pci_private *private = hose->private_data;

	if (private == NULL)
		return NULL;

	return private->fake_config[devno][fn];
}

static struct celleb_pci_resource *get_resource_start(
				struct pci_controller *hose,
				int devno, int fn)
{
	struct celleb_pci_private *private = hose->private_data;

	if (private == NULL)
		return NULL;

	return private->res[devno][fn];
}


static void celleb_config_read_fake(unsigned char *config, int where,
				    int size, u32 *val)
{
	char *p = config + where;

	switch (size) {
	case 1:
		*val = celleb_fake_config_readb(p);
		break;
	case 2:
		*val = celleb_fake_config_readw(p);
		break;
	case 4:
		*val = celleb_fake_config_readl(p);
		break;
	}
}

static void celleb_config_write_fake(unsigned char *config, int where,
				     int size, u32 val)
{
	char *p = config + where;

	switch (size) {
	case 1:
		celleb_fake_config_writeb(val, p);
		break;
	case 2:
		celleb_fake_config_writew(val, p);
		break;
	case 4:
		celleb_fake_config_writel(val, p);
		break;
	}
}

static int celleb_fake_pci_read_config(struct pci_bus *bus,
		unsigned int devfn, int where, int size, u32 *val)
{
	char *config;
	struct device_node *node;
	struct pci_controller *hose;
	unsigned int devno = devfn >> 3;
	unsigned int fn = devfn & 0x7;

	/* allignment check */
	BUG_ON(where % size);

	pr_debug("    fake read: bus=0x%x, ", bus->number);
	node = (struct device_node *)bus->sysdata;
	hose = pci_find_hose_for_OF_device(node);
	config = get_fake_config_start(hose, devno, fn);

	pr_debug("devno=0x%x, where=0x%x, size=0x%x, ", devno, where, size);
	if (!config) {
		pr_debug("failed\n");
		return PCIBIOS_DEVICE_NOT_FOUND;
	}

	celleb_config_read_fake(config, where, size, val);
	pr_debug("val=0x%x\n", *val);

	return PCIBIOS_SUCCESSFUL;
}


static int celleb_fake_pci_write_config(struct pci_bus *bus,
		unsigned int devfn, int where, int size, u32 val)
{
	char *config;
	struct device_node *node;
	struct pci_controller *hose;
	struct celleb_pci_resource *res;
	unsigned int devno = devfn >> 3;
	unsigned int fn = devfn & 0x7;

	/* allignment check */
	BUG_ON(where % size);

	node = (struct device_node *)bus->sysdata;
	hose = pci_find_hose_for_OF_device(node);
	config = get_fake_config_start(hose, devno, fn);

	if (!config)
		return PCIBIOS_DEVICE_NOT_FOUND;

	if (val == ~0) {
		int i = (where - PCI_BASE_ADDRESS_0) >> 3;

		switch (where) {
		case PCI_BASE_ADDRESS_0:
		case PCI_BASE_ADDRESS_2:
			if (size != 4)
				return PCIBIOS_DEVICE_NOT_FOUND;
			res = get_resource_start(hose, devno, fn);
			if (!res)
				return PCIBIOS_DEVICE_NOT_FOUND;
			celleb_config_write_fake(config, where, size,
					(res->r[i].end - res->r[i].start));
			return PCIBIOS_SUCCESSFUL;
		case PCI_BASE_ADDRESS_1:
		case PCI_BASE_ADDRESS_3:
		case PCI_BASE_ADDRESS_4:
		case PCI_BASE_ADDRESS_5:
			break;
		default:
			break;
		}
	}

	celleb_config_write_fake(config, where, size, val);
	pr_debug("    fake write: where=%x, size=%d, val=%x\n",
		 where, size, val);

	return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops celleb_fake_pci_ops = {
	.read = celleb_fake_pci_read_config,
	.write = celleb_fake_pci_write_config,
};

static inline void celleb_setup_pci_base_addrs(struct pci_controller *hose,
					unsigned int devno, unsigned int fn,
					unsigned int num_base_addr)
{
	u32 val;
	unsigned char *config;
	struct celleb_pci_resource *res;

	config = get_fake_config_start(hose, devno, fn);
	res = get_resource_start(hose, devno, fn);

	if (!config || !res)
		return;

	switch (num_base_addr) {
	case 3:
		val = (res->r[2].start & 0xfffffff0)
		    | PCI_BASE_ADDRESS_MEM_TYPE_64;
		celleb_config_write_fake(config, PCI_BASE_ADDRESS_4, 4, val);
		val = res->r[2].start >> 32;
		celleb_config_write_fake(config, PCI_BASE_ADDRESS_5, 4, val);
		/* FALLTHROUGH */
	case 2:
		val = (res->r[1].start & 0xfffffff0)
		    | PCI_BASE_ADDRESS_MEM_TYPE_64;
		celleb_config_write_fake(config, PCI_BASE_ADDRESS_2, 4, val);
		val = res->r[1].start >> 32;
		celleb_config_write_fake(config, PCI_BASE_ADDRESS_3, 4, val);
		/* FALLTHROUGH */
	case 1:
		val = (res->r[0].start & 0xfffffff0)
		    | PCI_BASE_ADDRESS_MEM_TYPE_64;
		celleb_config_write_fake(config, PCI_BASE_ADDRESS_0, 4, val);
		val = res->r[0].start >> 32;
		celleb_config_write_fake(config, PCI_BASE_ADDRESS_1, 4, val);
		break;
	}

	val = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
	celleb_config_write_fake(config, PCI_COMMAND, 2, val);
}

static int __init celleb_setup_fake_pci_device(struct device_node *node,
					       struct pci_controller *hose)
{
	unsigned int rlen;
	int num_base_addr = 0;
	u32 val;
	const u32 *wi0, *wi1, *wi2, *wi3, *wi4;
	unsigned int devno, fn;
	struct celleb_pci_private *private = hose->private_data;
	unsigned char **config = NULL;
	struct celleb_pci_resource **res = NULL;
	const char *name;
	const unsigned long *li;
	int size, result;

	if (private == NULL) {
		printk(KERN_ERR "PCI: "
		       "memory space for pci controller is not assigned\n");
		goto error;
	}

	name = of_get_property(node, "model", &rlen);
	if (!name) {
		printk(KERN_ERR "PCI: model property not found.\n");
		goto error;
	}

	wi4 = of_get_property(node, "reg", &rlen);
	if (wi4 == NULL)
		goto error;

	devno = ((wi4[0] >> 8) & 0xff) >> 3;
	fn = (wi4[0] >> 8) & 0x7;

	pr_debug("PCI: celleb_setup_fake_pci() %s devno=%x fn=%x\n", name,
		 devno, fn);

	size = 256;
	config = &private->fake_config[devno][fn];
	*config = alloc_maybe_bootmem(size, GFP_KERNEL);
	if (*config == NULL) {
		printk(KERN_ERR "PCI: "
		       "not enough memory for fake configuration space\n");
		goto error;
	}
	pr_debug("PCI: fake config area assigned 0x%016lx\n",
		 (unsigned long)*config);

	size = sizeof(struct celleb_pci_resource);
	res = &private->res[devno][fn];
	*res = alloc_maybe_bootmem(size, GFP_KERNEL);
	if (*res == NULL) {
		printk(KERN_ERR
		       "PCI: not enough memory for resource data space\n");
		goto error;
	}
	pr_debug("PCI: res assigned 0x%016lx\n", (unsigned long)*res);

	wi0 = of_get_property(node, "device-id", NULL);
	wi1 = of_get_property(node, "vendor-id", NULL);
	wi2 = of_get_property(node, "class-code", NULL);
	wi3 = of_get_property(node, "revision-id", NULL);
	if (!wi0 || !wi1 || !wi2 || !wi3) {
		printk(KERN_ERR "PCI: Missing device tree properties.\n");
		goto error;
	}

	celleb_config_write_fake(*config, PCI_DEVICE_ID, 2, wi0[0] & 0xffff);
	celleb_config_write_fake(*config, PCI_VENDOR_ID, 2, wi1[0] & 0xffff);
	pr_debug("class-code = 0x%08x\n", wi2[0]);

	celleb_config_write_fake(*config, PCI_CLASS_PROG, 1, wi2[0] & 0xff);
	celleb_config_write_fake(*config, PCI_CLASS_DEVICE, 2,
				 (wi2[0] >> 8) & 0xffff);
	celleb_config_write_fake(*config, PCI_REVISION_ID, 1, wi3[0]);

	while (num_base_addr < MAX_PCI_BASE_ADDRS) {
		result = of_address_to_resource(node,
				num_base_addr, &(*res)->r[num_base_addr]);
		if (result)
			break;
		num_base_addr++;
	}

	celleb_setup_pci_base_addrs(hose, devno, fn, num_base_addr);

	li = of_get_property(node, "interrupts", &rlen);
	if (!li) {
		printk(KERN_ERR "PCI: interrupts not found.\n");
		goto error;
	}
	val = li[0];
	celleb_config_write_fake(*config, PCI_INTERRUPT_PIN, 1, 1);
	celleb_config_write_fake(*config, PCI_INTERRUPT_LINE, 1, val);

#ifdef DEBUG
	pr_debug("PCI: %s irq=%ld\n", name, li[0]);
	for (i = 0; i < 6; i++) {
		celleb_config_read_fake(*config,
					PCI_BASE_ADDRESS_0 + 0x4 * i, 4,
					&val);
		pr_debug("PCI: %s fn=%d base_address_%d=0x%x\n",
			 name, fn, i, val);
	}
#endif

	celleb_config_write_fake(*config, PCI_HEADER_TYPE, 1,
				 PCI_HEADER_TYPE_NORMAL);

	return 0;

error:
	if (mem_init_done) {
		if (config && *config)
			kfree(*config);
		if (res && *res)
			kfree(*res);

	} else {
		if (config && *config) {
			size = 256;
			free_bootmem((unsigned long)(*config), size);
		}
		if (res && *res) {
			size = sizeof(struct celleb_pci_resource);
			free_bootmem((unsigned long)(*res), size);
		}
	}

	return 1;
}

static int __init phb_set_bus_ranges(struct device_node *dev,
				     struct pci_controller *phb)
{
	const int *bus_range;
	unsigned int len;

	bus_range = of_get_property(dev, "bus-range", &len);
	if (bus_range == NULL || len < 2 * sizeof(int))
		return 1;

	phb->first_busno = bus_range[0];
	phb->last_busno = bus_range[1];

	return 0;
}

static void __init celleb_alloc_private_mem(struct pci_controller *hose)
{
	hose->private_data =
		alloc_maybe_bootmem(sizeof(struct celleb_pci_private),
			GFP_KERNEL);
}

static int __init celleb_setup_fake_pci(struct device_node *dev,
					struct pci_controller *phb)
{
	struct device_node *node;

	phb->ops = &celleb_fake_pci_ops;
	celleb_alloc_private_mem(phb);

	for (node = of_get_next_child(dev, NULL);
	     node != NULL; node = of_get_next_child(dev, node))
		celleb_setup_fake_pci_device(node, phb);

	return 0;
}

static struct celleb_phb_spec celleb_fake_pci_spec __initdata = {
	.setup = celleb_setup_fake_pci,
};

static struct of_device_id celleb_phb_match[] __initdata = {
	{
		.name = "pci-pseudo",
		.data = &celleb_fake_pci_spec,
	}, {
		.name = "epci",
		.data = &celleb_epci_spec,
	}, {
		.name = "pcie",
		.data = &celleb_pciex_spec,
	}, {
	},
};

static int __init celleb_io_workaround_init(struct pci_controller *phb,
					    struct celleb_phb_spec *phb_spec)
{
	if (phb_spec->ops) {
		iowa_register_bus(phb, phb_spec->ops, phb_spec->iowa_init,
				  phb_spec->iowa_data);
		io_workaround_init();
	}

	return 0;
}

int __init celleb_setup_phb(struct pci_controller *phb)
{
	struct device_node *dev = phb->dn;
	const struct of_device_id *match;
	struct celleb_phb_spec *phb_spec;
	int rc;

	match = of_match_node(celleb_phb_match, dev);
	if (!match)
		return 1;

	phb_set_bus_ranges(dev, phb);
	phb->buid = 1;

	phb_spec = match->data;
	rc = (*phb_spec->setup)(dev, phb);
	if (rc)
		return 1;

	return celleb_io_workaround_init(phb, phb_spec);
}

int celleb_pci_probe_mode(struct pci_bus *bus)
{
	return PCI_PROBE_DEVTREE;
}
