/*
 * 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/machdep.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>

#include "pci.h"
#include "interrupt.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;
}

void __init fake_pci_workaround_init(struct pci_controller *phb)
{
	/**
	 *  We will add fake pci bus to scc_pci_bus for the purpose to improve
	 *  I/O Macro performance. But device-tree and device drivers
	 *  are not ready to use address with a token.
	 */

	/* celleb_pci_add_one(phb, NULL); */
}

static struct of_device_id celleb_phb_match[] __initdata = {
	{
		.name = "pci-pseudo",
		.data = celleb_setup_fake_pci,
	}, {
		.name = "epci",
		.data = celleb_setup_epci,
	}, {
	},
};

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

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

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

	setup_func = match->data;
	return (*setup_func)(dev, phb);
}

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