/*
 * IO workarounds for PCI on Celleb/Cell platform
 *
 * (C) Copyright 2006-2007 TOSHIBA CORPORATION
 *
 * 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/of_platform.h>
#include <linux/slab.h>
#include <linux/io.h>

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

#define SPIDER_PCI_DISABLE_PREFETCH

struct spiderpci_iowa_private {
	void __iomem *regs;
};

static void spiderpci_io_flush(struct iowa_bus *bus)
{
	struct spiderpci_iowa_private *priv;
	u32 val;

	priv = bus->private;
	val = in_be32(priv->regs + SPIDER_PCI_DUMMY_READ);
	iosync();
}

#define SPIDER_PCI_MMIO_READ(name, ret)					\
static ret spiderpci_##name(const PCI_IO_ADDR addr)			\
{									\
	ret val = __do_##name(addr);					\
	spiderpci_io_flush(iowa_mem_find_bus(addr));			\
	return val;							\
}

#define SPIDER_PCI_MMIO_READ_STR(name)					\
static void spiderpci_##name(const PCI_IO_ADDR addr, void *buf, 	\
			     unsigned long count)			\
{									\
	__do_##name(addr, buf, count);					\
	spiderpci_io_flush(iowa_mem_find_bus(addr));			\
}

SPIDER_PCI_MMIO_READ(readb, u8)
SPIDER_PCI_MMIO_READ(readw, u16)
SPIDER_PCI_MMIO_READ(readl, u32)
SPIDER_PCI_MMIO_READ(readq, u64)
SPIDER_PCI_MMIO_READ(readw_be, u16)
SPIDER_PCI_MMIO_READ(readl_be, u32)
SPIDER_PCI_MMIO_READ(readq_be, u64)
SPIDER_PCI_MMIO_READ_STR(readsb)
SPIDER_PCI_MMIO_READ_STR(readsw)
SPIDER_PCI_MMIO_READ_STR(readsl)

static void spiderpci_memcpy_fromio(void *dest, const PCI_IO_ADDR src,
				    unsigned long n)
{
	__do_memcpy_fromio(dest, src, n);
	spiderpci_io_flush(iowa_mem_find_bus(src));
}

static int __init spiderpci_pci_setup_chip(struct pci_controller *phb,
					   void __iomem *regs)
{
	void *dummy_page_va;
	dma_addr_t dummy_page_da;

#ifdef SPIDER_PCI_DISABLE_PREFETCH
	u32 val = in_be32(regs + SPIDER_PCI_VCI_CNTL_STAT);
	pr_debug("SPIDER_IOWA:PVCI_Control_Status was 0x%08x\n", val);
	out_be32(regs + SPIDER_PCI_VCI_CNTL_STAT, val | 0x8);
#endif /* SPIDER_PCI_DISABLE_PREFETCH */

	/* setup dummy read */
	/*
	 * On CellBlade, we can't know that which XDR memory is used by
	 * kmalloc() to allocate dummy_page_va.
	 * In order to imporve the performance, the XDR which is used to
	 * allocate dummy_page_va is the nearest the spider-pci.
	 * We have to select the CBE which is the nearest the spider-pci
	 * to allocate memory from the best XDR, but I don't know that
	 * how to do.
	 *
	 * Celleb does not have this problem, because it has only one XDR.
	 */
	dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!dummy_page_va) {
		pr_err("SPIDERPCI-IOWA:Alloc dummy_page_va failed.\n");
		return -1;
	}

	dummy_page_da = dma_map_single(phb->parent, dummy_page_va,
				       PAGE_SIZE, DMA_FROM_DEVICE);
	if (dma_mapping_error(phb->parent, dummy_page_da)) {
		pr_err("SPIDER-IOWA:Map dummy page filed.\n");
		kfree(dummy_page_va);
		return -1;
	}

	out_be32(regs + SPIDER_PCI_DUMMY_READ_BASE, dummy_page_da);

	return 0;
}

int __init spiderpci_iowa_init(struct iowa_bus *bus, void *data)
{
	void __iomem *regs = NULL;
	struct spiderpci_iowa_private *priv;
	struct device_node *np = bus->phb->dn;
	struct resource r;
	unsigned long offset = (unsigned long)data;

	pr_debug("SPIDERPCI-IOWA:Bus initialize for spider(%s)\n",
		 np->full_name);

	priv = kzalloc(sizeof(struct spiderpci_iowa_private), GFP_KERNEL);
	if (!priv) {
		pr_err("SPIDERPCI-IOWA:"
		       "Can't allocate struct spiderpci_iowa_private");
		return -1;
	}

	if (of_address_to_resource(np, 0, &r)) {
		pr_err("SPIDERPCI-IOWA:Can't get resource.\n");
		goto error;
	}

	regs = ioremap(r.start + offset, SPIDER_PCI_REG_SIZE);
	if (!regs) {
		pr_err("SPIDERPCI-IOWA:ioremap failed.\n");
		goto error;
	}
	priv->regs = regs;
	bus->private = priv;

	if (spiderpci_pci_setup_chip(bus->phb, regs))
		goto error;

	return 0;

error:
	kfree(priv);
	bus->private = NULL;

	if (regs)
		iounmap(regs);

	return -1;
}

struct ppc_pci_io spiderpci_ops = {
	.readb = spiderpci_readb,
	.readw = spiderpci_readw,
	.readl = spiderpci_readl,
	.readq = spiderpci_readq,
	.readw_be = spiderpci_readw_be,
	.readl_be = spiderpci_readl_be,
	.readq_be = spiderpci_readq_be,
	.readsb = spiderpci_readsb,
	.readsw = spiderpci_readsw,
	.readsl = spiderpci_readsl,
	.memcpy_fromio = spiderpci_memcpy_fromio,
};

