/*
 * Support for Celleb PCI-Express.
 *
 * (C) Copyright 2007-2008 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/pci.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/delay.h>
#include <linux/interrupt.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/iommu.h>
#include <asm/byteorder.h>

#include "celleb_scc.h"
#include "celleb_pci.h"

#define PEX_IN(base, off)	in_be32((void __iomem *)(base) + (off))
#define PEX_OUT(base, off, data) out_be32((void __iomem *)(base) + (off), (data))

static void scc_pciex_io_flush(struct iowa_bus *bus)
{
	(void)PEX_IN(bus->phb->cfg_addr, PEXDMRDEN0);
}

/*
 * Memory space access to device on PCIEX
 */
#define PCIEX_MMIO_READ(name, ret)					\
static ret scc_pciex_##name(const PCI_IO_ADDR addr)			\
{									\
	ret val = __do_##name(addr);					\
	scc_pciex_io_flush(iowa_mem_find_bus(addr));			\
	return val;							\
}

#define PCIEX_MMIO_READ_STR(name)					\
static void scc_pciex_##name(const PCI_IO_ADDR addr, void *buf,		\
			     unsigned long count)			\
{									\
	__do_##name(addr, buf, count);					\
	scc_pciex_io_flush(iowa_mem_find_bus(addr));			\
}

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

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

/*
 * I/O port access to devices on PCIEX.
 */

static inline unsigned long get_bus_address(struct pci_controller *phb,
					    unsigned long port)
{
	return port - ((unsigned long)(phb->io_base_virt) - _IO_BASE);
}

static u32 scc_pciex_read_port(struct pci_controller *phb,
			       unsigned long port, int size)
{
	unsigned int byte_enable;
	unsigned int cmd, shift;
	unsigned long addr;
	u32 data, ret;

	BUG_ON(((port & 0x3ul) + size) > 4);

	addr = get_bus_address(phb, port);
	shift = addr & 0x3ul;
	byte_enable = ((1 << size) - 1) << shift;
	cmd = PEXDCMND_IO_READ | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
	PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
	PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
	data = PEX_IN(phb->cfg_addr, PEXDRDATA);
	ret = (data >> (shift * 8)) & (0xFFFFFFFF >> ((4 - size) * 8));

	pr_debug("PCIEX:PIO READ:port=0x%lx, addr=0x%lx, size=%d, be=%x,"
		 " cmd=%x, data=%x, ret=%x\n", port, addr, size, byte_enable,
		 cmd, data, ret);

	return ret;
}

static void scc_pciex_write_port(struct pci_controller *phb,
				 unsigned long port, int size, u32 val)
{
	unsigned int byte_enable;
	unsigned int cmd, shift;
	unsigned long addr;
	u32 data;

	BUG_ON(((port & 0x3ul) + size) > 4);

	addr = get_bus_address(phb, port);
	shift = addr & 0x3ul;
	byte_enable = ((1 << size) - 1) << shift;
	cmd = PEXDCMND_IO_WRITE | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
	data = (val & (0xFFFFFFFF >> (4 - size) * 8)) << (shift * 8);
	PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
	PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
	PEX_OUT(phb->cfg_addr, PEXDWDATA, data);

	pr_debug("PCIEX:PIO WRITE:port=0x%lx, addr=%lx, size=%d, val=%x,"
		 " be=%x, cmd=%x, data=%x\n", port, addr, size, val,
		 byte_enable, cmd, data);
}

static u8 __scc_pciex_inb(struct pci_controller *phb, unsigned long port)
{
	return (u8)scc_pciex_read_port(phb, port, 1);
}

static u16 __scc_pciex_inw(struct pci_controller *phb, unsigned long port)
{
	u32 data;
	if ((port & 0x3ul) < 3)
		data = scc_pciex_read_port(phb, port, 2);
	else {
		u32 d1 = scc_pciex_read_port(phb, port, 1);
		u32 d2 = scc_pciex_read_port(phb, port + 1, 1);
		data = d1 | (d2 << 8);
	}
	return (u16)data;
}

static u32 __scc_pciex_inl(struct pci_controller *phb, unsigned long port)
{
	unsigned int mod = port & 0x3ul;
	u32 data;
	if (mod == 0)
		data = scc_pciex_read_port(phb, port, 4);
	else {
		u32 d1 = scc_pciex_read_port(phb, port, 4 - mod);
		u32 d2 = scc_pciex_read_port(phb, port + 1, mod);
		data = d1 | (d2 << (mod * 8));
	}
	return data;
}

static void __scc_pciex_outb(struct pci_controller *phb,
			     u8 val, unsigned long port)
{
	scc_pciex_write_port(phb, port, 1, (u32)val);
}

static void __scc_pciex_outw(struct pci_controller *phb,
			     u16 val, unsigned long port)
{
	if ((port & 0x3ul) < 3)
		scc_pciex_write_port(phb, port, 2, (u32)val);
	else {
		u32 d1 = val & 0x000000FF;
		u32 d2 = (val & 0x0000FF00) >> 8;
		scc_pciex_write_port(phb, port, 1, d1);
		scc_pciex_write_port(phb, port + 1, 1, d2);
	}
}

static void __scc_pciex_outl(struct pci_controller *phb,
			     u32 val, unsigned long port)
{
	unsigned int mod = port & 0x3ul;
	if (mod == 0)
		scc_pciex_write_port(phb, port, 4, val);
	else {
		u32 d1 = val & (0xFFFFFFFFul >> (mod * 8));
		u32 d2 = val >> ((4 - mod) * 8);
		scc_pciex_write_port(phb, port, 4 - mod, d1);
		scc_pciex_write_port(phb, port + 1, mod, d2);
	}
}

#define PCIEX_PIO_FUNC(size, name)					\
static u##size scc_pciex_in##name(unsigned long port)			\
{									\
	struct iowa_bus *bus = iowa_pio_find_bus(port);			\
	u##size data = __scc_pciex_in##name(bus->phb, port);		\
	scc_pciex_io_flush(bus);					\
	return data;							\
}									\
static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \
{									\
	struct iowa_bus *bus = iowa_pio_find_bus(p);			\
	u##size *dst = b;						\
	for (; c != 0; c--, dst++)					\
		*dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \
	scc_pciex_io_flush(bus);					\
}									\
static void scc_pciex_out##name(u##size val, unsigned long port)	\
{									\
	struct iowa_bus *bus = iowa_pio_find_bus(port);			\
	__scc_pciex_out##name(bus->phb, val, port);			\
}									\
static void scc_pciex_outs##name(unsigned long p, const void *b,	\
				 unsigned long c)			\
{									\
	struct iowa_bus *bus = iowa_pio_find_bus(p);			\
	const u##size *src = b;						\
	for (; c != 0; c--, src++)					\
		__scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \
}
#define cpu_to_le8(x) (x)
#define le8_to_cpu(x) (x)
PCIEX_PIO_FUNC(8, b)
PCIEX_PIO_FUNC(16, w)
PCIEX_PIO_FUNC(32, l)

static struct ppc_pci_io scc_pciex_ops = {
	.readb = scc_pciex_readb,
	.readw = scc_pciex_readw,
	.readl = scc_pciex_readl,
	.readq = scc_pciex_readq,
	.readw_be = scc_pciex_readw_be,
	.readl_be = scc_pciex_readl_be,
	.readq_be = scc_pciex_readq_be,
	.readsb = scc_pciex_readsb,
	.readsw = scc_pciex_readsw,
	.readsl = scc_pciex_readsl,
	.memcpy_fromio = scc_pciex_memcpy_fromio,
	.inb = scc_pciex_inb,
	.inw = scc_pciex_inw,
	.inl = scc_pciex_inl,
	.outb = scc_pciex_outb,
	.outw = scc_pciex_outw,
	.outl = scc_pciex_outl,
	.insb = scc_pciex_insb,
	.insw = scc_pciex_insw,
	.insl = scc_pciex_insl,
	.outsb = scc_pciex_outsb,
	.outsw = scc_pciex_outsw,
	.outsl = scc_pciex_outsl,
};

static int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data)
{
	dma_addr_t dummy_page_da;
	void *dummy_page_va;

	dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!dummy_page_va) {
		pr_err("PCIEX:Alloc dummy_page_va failed\n");
		return -1;
	}

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

	PEX_OUT(bus->phb->cfg_addr, PEXDMRDADR0, dummy_page_da);

	return 0;
}

/*
 * config space access
 */
#define MK_PEXDADRS(bus_no, dev_no, func_no, addr) \
	((uint32_t)(((addr) & ~0x3UL) | \
	((bus_no) << PEXDADRS_BUSNO_SHIFT) | \
	((dev_no)  << PEXDADRS_DEVNO_SHIFT) | \
	((func_no) << PEXDADRS_FUNCNO_SHIFT)))

#define MK_PEXDCMND_BYTE_EN(addr, size) \
	((((0x1 << (size))-1) << ((addr) & 0x3)) << PEXDCMND_BYTE_EN_SHIFT)
#define MK_PEXDCMND(cmd, addr, size) ((cmd) | MK_PEXDCMND_BYTE_EN(addr, size))

static uint32_t config_read_pciex_dev(unsigned int __iomem *base,
		uint64_t bus_no, uint64_t dev_no, uint64_t func_no,
		uint64_t off, uint64_t size)
{
	uint32_t ret;
	uint32_t addr, cmd;

	addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
	cmd = MK_PEXDCMND(PEXDCMND_CONFIG_READ, off, size);
	PEX_OUT(base, PEXDADRS, addr);
	PEX_OUT(base, PEXDCMND, cmd);
	ret = (PEX_IN(base, PEXDRDATA)
		>> ((off & (4-size)) * 8)) & ((0x1 << (size * 8)) - 1);
	return ret;
}

static void config_write_pciex_dev(unsigned int __iomem *base, uint64_t bus_no,
	uint64_t dev_no, uint64_t func_no, uint64_t off, uint64_t size,
	uint32_t data)
{
	uint32_t addr, cmd;

	addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
	cmd = MK_PEXDCMND(PEXDCMND_CONFIG_WRITE, off, size);
	PEX_OUT(base, PEXDADRS, addr);
	PEX_OUT(base, PEXDCMND, cmd);
	PEX_OUT(base, PEXDWDATA,
		(data & ((0x1 << (size * 8)) - 1)) << ((off & (4-size)) * 8));
}

#define MK_PEXCADRS_BYTE_EN(off, len) \
	((((0x1 << (len)) - 1) << ((off) & 0x3)) << PEXCADRS_BYTE_EN_SHIFT)
#define MK_PEXCADRS(cmd, addr, size) \
	((cmd) | MK_PEXCADRS_BYTE_EN(addr, size) | ((addr) & ~0x3))
static uint32_t config_read_pciex_rc(unsigned int __iomem *base,
				     uint32_t where, uint32_t size)
{
	PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_READ, where, size));
	return (PEX_IN(base, PEXCRDATA)
		>> ((where & (4 - size)) * 8)) & ((0x1 << (size * 8)) - 1);
}

static void config_write_pciex_rc(unsigned int __iomem *base, uint32_t where,
				  uint32_t size, uint32_t val)
{
	uint32_t data;

	data = (val & ((0x1 << (size * 8)) - 1)) << ((where & (4 - size)) * 8);
	PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_WRITE, where, size));
	PEX_OUT(base, PEXCWDATA, data);
}

/* Interfaces */
/* Note: Work-around
 *  On SCC PCIEXC, one device is seen on all 32 dev_no.
 *  As SCC PCIEXC can have only one device on the bus, we look only one dev_no.
 * (dev_no = 1)
 */
static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
				 int where, int size, unsigned int *val)
{
	struct device_node *dn;
	struct pci_controller *phb;

	dn = bus->sysdata;
	phb = pci_find_hose_for_OF_device(dn);

	if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
		*val = ~0;
		return PCIBIOS_DEVICE_NOT_FOUND;
	}

	if (bus->number == 0 && PCI_SLOT(devfn) == 0)
		*val = config_read_pciex_rc(phb->cfg_addr, where, size);
	else
		*val = config_read_pciex_dev(phb->cfg_addr, bus->number,
				PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);

	return PCIBIOS_SUCCESSFUL;
}

static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
				  int where, int size, unsigned int val)
{
	struct device_node *dn;
	struct pci_controller *phb;

	dn = bus->sysdata;
	phb = pci_find_hose_for_OF_device(dn);

	if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
		return PCIBIOS_DEVICE_NOT_FOUND;

	if (bus->number == 0 && PCI_SLOT(devfn) == 0)
		config_write_pciex_rc(phb->cfg_addr, where, size, val);
	else
		config_write_pciex_dev(phb->cfg_addr, bus->number,
			PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
	return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops scc_pciex_pci_ops = {
	scc_pciex_read_config,
	scc_pciex_write_config,
};

static void pciex_clear_intr_all(unsigned int __iomem *base)
{
	PEX_OUT(base, PEXAERRSTS, 0xffffffff);
	PEX_OUT(base, PEXPRERRSTS, 0xffffffff);
	PEX_OUT(base, PEXINTSTS, 0xffffffff);
}

#if 0
static void pciex_disable_intr_all(unsigned int *base)
{
	PEX_OUT(base, PEXINTMASK,   0x0);
	PEX_OUT(base, PEXAERRMASK,  0x0);
	PEX_OUT(base, PEXPRERRMASK, 0x0);
	PEX_OUT(base, PEXVDMASK,    0x0);
}
#endif

static void pciex_enable_intr_all(unsigned int __iomem *base)
{
	PEX_OUT(base, PEXINTMASK, 0x0000e7f1);
	PEX_OUT(base, PEXAERRMASK, 0x03ff01ff);
	PEX_OUT(base, PEXPRERRMASK, 0x0001010f);
	PEX_OUT(base, PEXVDMASK, 0x00000001);
}

static void pciex_check_status(unsigned int __iomem *base)
{
	uint32_t err = 0;
	uint32_t intsts, aerr, prerr, rcvcp, lenerr;
	uint32_t maea, maec;

	intsts = PEX_IN(base, PEXINTSTS);
	aerr = PEX_IN(base, PEXAERRSTS);
	prerr = PEX_IN(base, PEXPRERRSTS);
	rcvcp = PEX_IN(base, PEXRCVCPLIDA);
	lenerr = PEX_IN(base, PEXLENERRIDA);

	if (intsts || aerr || prerr || rcvcp || lenerr)
		err = 1;

	pr_info("PCEXC interrupt!!\n");
	pr_info("PEXINTSTS    :0x%08x\n", intsts);
	pr_info("PEXAERRSTS   :0x%08x\n", aerr);
	pr_info("PEXPRERRSTS  :0x%08x\n", prerr);
	pr_info("PEXRCVCPLIDA :0x%08x\n", rcvcp);
	pr_info("PEXLENERRIDA :0x%08x\n", lenerr);

	/* print detail of Protection Error */
	if (intsts & 0x00004000) {
		uint32_t i, n;
		for (i = 0; i < 4; i++) {
			n = 1 << i;
			if (prerr & n) {
				maea = PEX_IN(base, PEXMAEA(i));
				maec = PEX_IN(base, PEXMAEC(i));
				pr_info("PEXMAEC%d     :0x%08x\n", i, maec);
				pr_info("PEXMAEA%d     :0x%08x\n", i, maea);
			}
		}
	}

	if (err)
		pciex_clear_intr_all(base);
}

static irqreturn_t pciex_handle_internal_irq(int irq, void *dev_id)
{
	struct pci_controller *phb = dev_id;

	pr_debug("PCIEX:pciex_handle_internal_irq(irq=%d)\n", irq);

	BUG_ON(phb->cfg_addr == NULL);

	pciex_check_status(phb->cfg_addr);

	return IRQ_HANDLED;
}

static __init int celleb_setup_pciex(struct device_node *node,
				     struct pci_controller *phb)
{
	struct resource	r;
	struct of_irq oirq;
	int virq;

	/* SMMIO registers; used inside this file */
	if (of_address_to_resource(node, 0, &r)) {
		pr_err("PCIEXC:Failed to get config resource.\n");
		return 1;
	}
	phb->cfg_addr = ioremap(r.start, r.end - r.start + 1);
	if (!phb->cfg_addr) {
		pr_err("PCIEXC:Failed to remap SMMIO region.\n");
		return 1;
	}

	/* Not use cfg_data,  cmd and data regs are near address reg */
	phb->cfg_data = NULL;

	/* set pci_ops */
	phb->ops = &scc_pciex_pci_ops;

	/* internal interrupt handler */
	if (of_irq_map_one(node, 1, &oirq)) {
		pr_err("PCIEXC:Failed to map irq\n");
		goto error;
	}
	virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
				     oirq.size);
	if (request_irq(virq, pciex_handle_internal_irq,
			IRQF_DISABLED, "pciex", (void *)phb)) {
		pr_err("PCIEXC:Failed to request irq\n");
		goto error;
	}

	/* enable all interrupts */
	pciex_clear_intr_all(phb->cfg_addr);
	pciex_enable_intr_all(phb->cfg_addr);
	/* MSI: TBD */

	return 0;

error:
	phb->cfg_data = NULL;
	if (phb->cfg_addr)
		iounmap(phb->cfg_addr);
	phb->cfg_addr = NULL;
	return 1;
}

struct celleb_phb_spec celleb_pciex_spec __initdata = {
	.setup = celleb_setup_pciex,
	.ops = &scc_pciex_ops,
	.iowa_init = &scc_pciex_iowa_init,
};
