/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
 */

#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/io.h>

#include "pci-bcm63xx.h"

/*
 * swizzle 32bits data to return only the needed part
 */
static int postprocess_read(u32 data, int where, unsigned int size)
{
	u32 ret;

	ret = 0;
	switch (size) {
	case 1:
		ret = (data >> ((where & 3) << 3)) & 0xff;
		break;
	case 2:
		ret = (data >> ((where & 3) << 3)) & 0xffff;
		break;
	case 4:
		ret = data;
		break;
	}
	return ret;
}

static int preprocess_write(u32 orig_data, u32 val, int where,
			    unsigned int size)
{
	u32 ret;

	ret = 0;
	switch (size) {
	case 1:
		ret = (orig_data & ~(0xff << ((where & 3) << 3))) |
			(val << ((where & 3) << 3));
		break;
	case 2:
		ret = (orig_data & ~(0xffff << ((where & 3) << 3))) |
			(val << ((where & 3) << 3));
		break;
	case 4:
		ret = val;
		break;
	}
	return ret;
}

/*
 * setup hardware for a configuration cycle with given parameters
 */
static int bcm63xx_setup_cfg_access(int type, unsigned int busn,
				    unsigned int devfn, int where)
{
	unsigned int slot, func, reg;
	u32 val;

	slot = PCI_SLOT(devfn);
	func = PCI_FUNC(devfn);
	reg = where >> 2;

	/* sanity check */
	if (slot > (MPI_L2PCFG_DEVNUM_MASK >> MPI_L2PCFG_DEVNUM_SHIFT))
		return 1;

	if (func > (MPI_L2PCFG_FUNC_MASK >> MPI_L2PCFG_FUNC_SHIFT))
		return 1;

	if (reg > (MPI_L2PCFG_REG_MASK >> MPI_L2PCFG_REG_SHIFT))
		return 1;

	/* ok, setup config access */
	val = (reg << MPI_L2PCFG_REG_SHIFT);
	val |= (func << MPI_L2PCFG_FUNC_SHIFT);
	val |= (slot << MPI_L2PCFG_DEVNUM_SHIFT);
	val |= MPI_L2PCFG_CFG_USEREG_MASK;
	val |= MPI_L2PCFG_CFG_SEL_MASK;
	/* type 0 cycle for local bus, type 1 cycle for anything else */
	if (type != 0) {
		/* FIXME: how to specify bus ??? */
		val |= (1 << MPI_L2PCFG_CFG_TYPE_SHIFT);
	}
	bcm_mpi_writel(val, MPI_L2PCFG_REG);

	return 0;
}

static int bcm63xx_do_cfg_read(int type, unsigned int busn,
				unsigned int devfn, int where, int size,
				u32 *val)
{
	u32 data;

	/* two phase cycle, first we write address, then read data at
	 * another location, caller already has a spinlock so no need
	 * to add one here  */
	if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
		return PCIBIOS_DEVICE_NOT_FOUND;
	iob();
	data = le32_to_cpu(__raw_readl(pci_iospace_start));
	/* restore IO space normal behaviour */
	bcm_mpi_writel(0, MPI_L2PCFG_REG);

	*val = postprocess_read(data, where, size);

	return PCIBIOS_SUCCESSFUL;
}

static int bcm63xx_do_cfg_write(int type, unsigned int busn,
				 unsigned int devfn, int where, int size,
				 u32 val)
{
	u32 data;

	/* two phase cycle, first we write address, then write data to
	 * another location, caller already has a spinlock so no need
	 * to add one here  */
	if (bcm63xx_setup_cfg_access(type, busn, devfn, where))
		return PCIBIOS_DEVICE_NOT_FOUND;
	iob();

	data = le32_to_cpu(__raw_readl(pci_iospace_start));
	data = preprocess_write(data, val, where, size);

	__raw_writel(cpu_to_le32(data), pci_iospace_start);
	wmb();
	/* no way to know the access is done, we have to wait */
	udelay(500);
	/* restore IO space normal behaviour */
	bcm_mpi_writel(0, MPI_L2PCFG_REG);

	return PCIBIOS_SUCCESSFUL;
}

static int bcm63xx_pci_read(struct pci_bus *bus, unsigned int devfn,
			     int where, int size, u32 *val)
{
	int type;

	type = bus->parent ? 1 : 0;

	if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
		return PCIBIOS_DEVICE_NOT_FOUND;

	return bcm63xx_do_cfg_read(type, bus->number, devfn,
				    where, size, val);
}

static int bcm63xx_pci_write(struct pci_bus *bus, unsigned int devfn,
			      int where, int size, u32 val)
{
	int type;

	type = bus->parent ? 1 : 0;

	if (type == 0 && PCI_SLOT(devfn) == CARDBUS_PCI_IDSEL)
		return PCIBIOS_DEVICE_NOT_FOUND;

	return bcm63xx_do_cfg_write(type, bus->number, devfn,
				     where, size, val);
}

struct pci_ops bcm63xx_pci_ops = {
	.read   = bcm63xx_pci_read,
	.write  = bcm63xx_pci_write
};

#ifdef CONFIG_CARDBUS
/*
 * emulate configuration read access on a cardbus bridge
 */
#define FAKE_CB_BRIDGE_SLOT	0x1e

static int fake_cb_bridge_bus_number = -1;

static struct {
	u16 pci_command;
	u8 cb_latency;
	u8 subordinate_busn;
	u8 cardbus_busn;
	u8 pci_busn;
	int bus_assigned;
	u16 bridge_control;

	u32 mem_base0;
	u32 mem_limit0;
	u32 mem_base1;
	u32 mem_limit1;

	u32 io_base0;
	u32 io_limit0;
	u32 io_base1;
	u32 io_limit1;
} fake_cb_bridge_regs;

static int fake_cb_bridge_read(int where, int size, u32 *val)
{
	unsigned int reg;
	u32 data;

	data = 0;
	reg = where >> 2;
	switch (reg) {
	case (PCI_VENDOR_ID >> 2):
	case (PCI_CB_SUBSYSTEM_VENDOR_ID >> 2):
		/* create dummy vendor/device id from our cpu id */
		data = (bcm63xx_get_cpu_id() << 16) | PCI_VENDOR_ID_BROADCOM;
		break;

	case (PCI_COMMAND >> 2):
		data = (PCI_STATUS_DEVSEL_SLOW << 16);
		data |= fake_cb_bridge_regs.pci_command;
		break;

	case (PCI_CLASS_REVISION >> 2):
		data = (PCI_CLASS_BRIDGE_CARDBUS << 16);
		break;

	case (PCI_CACHE_LINE_SIZE >> 2):
		data = (PCI_HEADER_TYPE_CARDBUS << 16);
		break;

	case (PCI_INTERRUPT_LINE >> 2):
		/* bridge control */
		data = (fake_cb_bridge_regs.bridge_control << 16);
		/* pin:intA line:0xff */
		data |= (0x1 << 8) | 0xff;
		break;

	case (PCI_CB_PRIMARY_BUS >> 2):
		data = (fake_cb_bridge_regs.cb_latency << 24);
		data |= (fake_cb_bridge_regs.subordinate_busn << 16);
		data |= (fake_cb_bridge_regs.cardbus_busn << 8);
		data |= fake_cb_bridge_regs.pci_busn;
		break;

	case (PCI_CB_MEMORY_BASE_0 >> 2):
		data = fake_cb_bridge_regs.mem_base0;
		break;

	case (PCI_CB_MEMORY_LIMIT_0 >> 2):
		data = fake_cb_bridge_regs.mem_limit0;
		break;

	case (PCI_CB_MEMORY_BASE_1 >> 2):
		data = fake_cb_bridge_regs.mem_base1;
		break;

	case (PCI_CB_MEMORY_LIMIT_1 >> 2):
		data = fake_cb_bridge_regs.mem_limit1;
		break;

	case (PCI_CB_IO_BASE_0 >> 2):
		/* | 1 for 32bits io support */
		data = fake_cb_bridge_regs.io_base0 | 0x1;
		break;

	case (PCI_CB_IO_LIMIT_0 >> 2):
		data = fake_cb_bridge_regs.io_limit0;
		break;

	case (PCI_CB_IO_BASE_1 >> 2):
		/* | 1 for 32bits io support */
		data = fake_cb_bridge_regs.io_base1 | 0x1;
		break;

	case (PCI_CB_IO_LIMIT_1 >> 2):
		data = fake_cb_bridge_regs.io_limit1;
		break;
	}

	*val = postprocess_read(data, where, size);
	return PCIBIOS_SUCCESSFUL;
}

/*
 * emulate configuration write access on a cardbus bridge
 */
static int fake_cb_bridge_write(int where, int size, u32 val)
{
	unsigned int reg;
	u32 data, tmp;
	int ret;

	ret = fake_cb_bridge_read((where & ~0x3), 4, &data);
	if (ret != PCIBIOS_SUCCESSFUL)
		return ret;

	data = preprocess_write(data, val, where, size);

	reg = where >> 2;
	switch (reg) {
	case (PCI_COMMAND >> 2):
		fake_cb_bridge_regs.pci_command = (data & 0xffff);
		break;

	case (PCI_CB_PRIMARY_BUS >> 2):
		fake_cb_bridge_regs.cb_latency = (data >> 24) & 0xff;
		fake_cb_bridge_regs.subordinate_busn = (data >> 16) & 0xff;
		fake_cb_bridge_regs.cardbus_busn = (data >> 8) & 0xff;
		fake_cb_bridge_regs.pci_busn = data & 0xff;
		if (fake_cb_bridge_regs.cardbus_busn)
			fake_cb_bridge_regs.bus_assigned = 1;
		break;

	case (PCI_INTERRUPT_LINE >> 2):
		tmp = (data >> 16) & 0xffff;
		/* disable memory prefetch support */
		tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM0;
		tmp &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1;
		fake_cb_bridge_regs.bridge_control = tmp;
		break;

	case (PCI_CB_MEMORY_BASE_0 >> 2):
		fake_cb_bridge_regs.mem_base0 = data;
		break;

	case (PCI_CB_MEMORY_LIMIT_0 >> 2):
		fake_cb_bridge_regs.mem_limit0 = data;
		break;

	case (PCI_CB_MEMORY_BASE_1 >> 2):
		fake_cb_bridge_regs.mem_base1 = data;
		break;

	case (PCI_CB_MEMORY_LIMIT_1 >> 2):
		fake_cb_bridge_regs.mem_limit1 = data;
		break;

	case (PCI_CB_IO_BASE_0 >> 2):
		fake_cb_bridge_regs.io_base0 = data;
		break;

	case (PCI_CB_IO_LIMIT_0 >> 2):
		fake_cb_bridge_regs.io_limit0 = data;
		break;

	case (PCI_CB_IO_BASE_1 >> 2):
		fake_cb_bridge_regs.io_base1 = data;
		break;

	case (PCI_CB_IO_LIMIT_1 >> 2):
		fake_cb_bridge_regs.io_limit1 = data;
		break;
	}

	return PCIBIOS_SUCCESSFUL;
}

static int bcm63xx_cb_read(struct pci_bus *bus, unsigned int devfn,
			   int where, int size, u32 *val)
{
	/* snoop access to slot 0x1e on root bus, we fake a cardbus
	 * bridge at this location */
	if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
		fake_cb_bridge_bus_number = bus->number;
		return fake_cb_bridge_read(where, size, val);
	}

	/* a  configuration  cycle for  the  device  behind the  cardbus
	 * bridge is  actually done as a  type 0 cycle  on the primary
	 * bus. This means that only  one device can be on the cardbus
	 * bus */
	if (fake_cb_bridge_regs.bus_assigned &&
	    bus->number == fake_cb_bridge_regs.cardbus_busn &&
	    PCI_SLOT(devfn) == 0)
		return bcm63xx_do_cfg_read(0, 0,
					   PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
					   where, size, val);

	return PCIBIOS_DEVICE_NOT_FOUND;
}

static int bcm63xx_cb_write(struct pci_bus *bus, unsigned int devfn,
			    int where, int size, u32 val)
{
	if (!bus->parent && PCI_SLOT(devfn) == FAKE_CB_BRIDGE_SLOT) {
		fake_cb_bridge_bus_number = bus->number;
		return fake_cb_bridge_write(where, size, val);
	}

	if (fake_cb_bridge_regs.bus_assigned &&
	    bus->number == fake_cb_bridge_regs.cardbus_busn &&
	    PCI_SLOT(devfn) == 0)
		return bcm63xx_do_cfg_write(0, 0,
					    PCI_DEVFN(CARDBUS_PCI_IDSEL, 0),
					    where, size, val);

	return PCIBIOS_DEVICE_NOT_FOUND;
}

struct pci_ops bcm63xx_cb_ops = {
	.read   = bcm63xx_cb_read,
	.write   = bcm63xx_cb_write,
};

/*
 * only one IO window, so it  cannot be shared by PCI and cardbus, use
 * fixup to choose and detect unhandled configuration
 */
static void bcm63xx_fixup(struct pci_dev *dev)
{
	static int io_window = -1;
	int i, found, new_io_window;
	u32 val;

	/* look for any io resource */
	found = 0;
	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
		if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
			found = 1;
			break;
		}
	}

	if (!found)
		return;

	/* skip our fake bus with only cardbus bridge on it */
	if (dev->bus->number == fake_cb_bridge_bus_number)
		return;

	/* find on which bus the device is */
	if (fake_cb_bridge_regs.bus_assigned &&
	    dev->bus->number == fake_cb_bridge_regs.cardbus_busn &&
	    PCI_SLOT(dev->devfn) == 0)
		new_io_window = 1;
	else
		new_io_window = 0;

	if (new_io_window == io_window)
		return;

	if (io_window != -1) {
		printk(KERN_ERR "bcm63xx: both PCI and cardbus devices "
		       "need IO, which hardware cannot do\n");
		return;
	}

	printk(KERN_INFO "bcm63xx: PCI IO window assigned to %s\n",
	       (new_io_window == 0) ? "PCI" : "cardbus");

	val = bcm_mpi_readl(MPI_L2PIOREMAP_REG);
	if (io_window)
		val |= MPI_L2PREMAP_IS_CARDBUS_MASK;
	else
		val &= ~MPI_L2PREMAP_IS_CARDBUS_MASK;
	bcm_mpi_writel(val, MPI_L2PIOREMAP_REG);

	io_window = new_io_window;
}

DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
#endif
