/*
 * linux/arch/mips/txx9/pci.c
 *
 * Based on linux/arch/mips/txx9/rbtx4927/setup.c,
 *	    linux/arch/mips/txx9/rbtx4938/setup.c,
 *	    and RBTX49xx patch from CELF patch archive.
 *
 * Copyright 2001-2005 MontaVista Software Inc.
 * Copyright (C) 1996, 97, 2001, 04  Ralf Baechle (ralf@linux-mips.org)
 * (C) Copyright TOSHIBA CORPORATION 2000-2001, 2004-2007
 *
 * 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.
 */
#include <linux/delay.h>
#include <linux/jiffies.h>
#include <linux/io.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
#ifdef CONFIG_TOSHIBA_FPCIB0
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <asm/i8259.h>
#include <asm/txx9/smsc_fdc37m81x.h>
#endif

static int __init
early_read_config_word(struct pci_controller *hose,
		       int top_bus, int bus, int devfn, int offset, u16 *value)
{
	struct pci_bus fake_bus;

	fake_bus.number = bus;
	fake_bus.sysdata = hose;
	fake_bus.ops = hose->pci_ops;

	if (bus != top_bus)
		/* Fake a parent bus structure. */
		fake_bus.parent = &fake_bus;
	else
		fake_bus.parent = NULL;

	return pci_bus_read_config_word(&fake_bus, devfn, offset, value);
}

int __init txx9_pci66_check(struct pci_controller *hose, int top_bus,
			    int current_bus)
{
	u32 pci_devfn;
	unsigned short vid;
	int cap66 = -1;
	u16 stat;
	int ret;

	/* It seems SLC90E66 needs some time after PCI reset... */
	mdelay(80);

	pr_info("PCI: Checking 66MHz capabilities...\n");

	for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
		if (PCI_FUNC(pci_devfn))
			continue;
		ret = early_read_config_word(hose, top_bus, current_bus,
					     pci_devfn, PCI_VENDOR_ID, &vid);
		if (ret != PCIBIOS_SUCCESSFUL)
			continue;
		if (vid == 0xffff)
			continue;

		/* check 66MHz capability */
		if (cap66 < 0)
			cap66 = 1;
		if (cap66) {
			early_read_config_word(hose, top_bus, current_bus,
					       pci_devfn, PCI_STATUS, &stat);
			if (!(stat & PCI_STATUS_66MHZ)) {
				pr_debug("PCI: %02x:%02x not 66MHz capable.\n",
					 current_bus, pci_devfn);
				cap66 = 0;
				break;
			}
		}
	}
	return cap66 > 0;
}

static struct resource primary_pci_mem_res[2] = {
	{ .name = "PCI MEM" },
	{ .name = "PCI MMIO" },
};
static struct resource primary_pci_io_res = { .name = "PCI IO" };
struct pci_controller txx9_primary_pcic = {
	.mem_resource = &primary_pci_mem_res[0],
	.io_resource = &primary_pci_io_res,
};

#ifdef CONFIG_64BIT
int txx9_pci_mem_high __initdata = 1;
#else
int txx9_pci_mem_high __initdata;
#endif

/*
 * allocate pci_controller and resources.
 * mem_base, io_base: physical address.	 0 for auto assignment.
 * mem_size and io_size means max size on auto assignment.
 * pcic must be &txx9_primary_pcic or NULL.
 */
struct pci_controller *__init
txx9_alloc_pci_controller(struct pci_controller *pcic,
			  unsigned long mem_base, unsigned long mem_size,
			  unsigned long io_base, unsigned long io_size)
{
	struct pcic {
		struct pci_controller c;
		struct resource r_mem[2];
		struct resource r_io;
	} *new = NULL;
	int min_size = 0x10000;

	if (!pcic) {
		new = kzalloc(sizeof(*new), GFP_KERNEL);
		if (!new)
			return NULL;
		new->r_mem[0].name = "PCI mem";
		new->r_mem[1].name = "PCI mmio";
		new->r_io.name = "PCI io";
		new->c.mem_resource = new->r_mem;
		new->c.io_resource = &new->r_io;
		pcic = &new->c;
	} else
		BUG_ON(pcic != &txx9_primary_pcic);
	pcic->io_resource->flags = IORESOURCE_IO;

	/*
	 * for auto assignment, first search a (big) region for PCI
	 * MEM, then search a region for PCI IO.
	 */
	if (mem_base) {
		pcic->mem_resource[0].start = mem_base;
		pcic->mem_resource[0].end = mem_base + mem_size - 1;
		if (request_resource(&iomem_resource, &pcic->mem_resource[0]))
			goto free_and_exit;
	} else {
		unsigned long min = 0, max = 0x20000000; /* low 512MB */
		if (!mem_size) {
			/* default size for auto assignment */
			if (txx9_pci_mem_high)
				mem_size = 0x20000000;	/* mem:512M(max) */
			else
				mem_size = 0x08000000;	/* mem:128M(max) */
		}
		if (txx9_pci_mem_high) {
			min = 0x20000000;
			max = 0xe0000000;
		}
		/* search free region for PCI MEM */
		for (; mem_size >= min_size; mem_size /= 2) {
			if (allocate_resource(&iomem_resource,
					      &pcic->mem_resource[0],
					      mem_size, min, max,
					      mem_size, NULL, NULL) == 0)
				break;
		}
		if (mem_size < min_size)
			goto free_and_exit;
	}

	pcic->mem_resource[1].flags = IORESOURCE_MEM | IORESOURCE_BUSY;
	if (io_base) {
		pcic->mem_resource[1].start = io_base;
		pcic->mem_resource[1].end = io_base + io_size - 1;
		if (request_resource(&iomem_resource, &pcic->mem_resource[1]))
			goto release_and_exit;
	} else {
		if (!io_size)
			/* default size for auto assignment */
			io_size = 0x01000000;	/* io:16M(max) */
		/* search free region for PCI IO in low 512MB */
		for (; io_size >= min_size; io_size /= 2) {
			if (allocate_resource(&iomem_resource,
					      &pcic->mem_resource[1],
					      io_size, 0, 0x20000000,
					      io_size, NULL, NULL) == 0)
				break;
		}
		if (io_size < min_size)
			goto release_and_exit;
		io_base = pcic->mem_resource[1].start;
	}

	pcic->mem_resource[0].flags = IORESOURCE_MEM;
	if (pcic == &txx9_primary_pcic &&
	    mips_io_port_base == (unsigned long)-1) {
		/* map ioport 0 to PCI I/O space address 0 */
		set_io_port_base(IO_BASE + pcic->mem_resource[1].start);
		pcic->io_resource->start = 0;
		pcic->io_offset = 0;	/* busaddr == ioaddr */
		pcic->io_map_base = IO_BASE + pcic->mem_resource[1].start;
	} else {
		/* physaddr to ioaddr */
		pcic->io_resource->start =
			io_base - (mips_io_port_base - IO_BASE);
		pcic->io_offset = io_base - (mips_io_port_base - IO_BASE);
		pcic->io_map_base = mips_io_port_base;
	}
	pcic->io_resource->end = pcic->io_resource->start + io_size - 1;

	pcic->mem_offset = 0;	/* busaddr == physaddr */

	pr_info("PCI: IO %pR MEM %pR\n", &pcic->mem_resource[1],
		&pcic->mem_resource[0]);

	/* register_pci_controller() will request MEM resource */
	release_resource(&pcic->mem_resource[0]);
	return pcic;
 release_and_exit:
	release_resource(&pcic->mem_resource[0]);
 free_and_exit:
	kfree(new);
	pr_err("PCI: Failed to allocate resources.\n");
	return NULL;
}

static int __init
txx9_arch_pci_init(void)
{
	PCIBIOS_MIN_IO = 0x8000;	/* reserve legacy I/O space */
	return 0;
}
arch_initcall(txx9_arch_pci_init);

/* IRQ/IDSEL mapping */
int txx9_pci_option =
#ifdef CONFIG_PICMG_PCI_BACKPLANE_DEFAULT
	TXX9_PCI_OPT_PICMG |
#endif
	TXX9_PCI_OPT_CLK_AUTO;

enum txx9_pci_err_action txx9_pci_err_action = TXX9_PCI_ERR_REPORT;

#ifdef CONFIG_TOSHIBA_FPCIB0
static irqreturn_t i8259_interrupt(int irq, void *dev_id)
{
	int isairq;

	isairq = i8259_irq();
	if (unlikely(isairq <= I8259A_IRQ_BASE))
		return IRQ_NONE;
	generic_handle_irq(isairq);
	return IRQ_HANDLED;
}

static int txx9_i8259_irq_setup(int irq)
{
	int err;

	init_i8259_irqs();
	err = request_irq(irq, &i8259_interrupt, IRQF_SHARED,
			  "cascade(i8259)", (void *)(long)irq);
	if (!err)
		pr_info("PCI-ISA bridge PIC (irq %d)\n", irq);
	return err;
}

static void __ref quirk_slc90e66_bridge(struct pci_dev *dev)
{
	int irq;	/* PCI/ISA Bridge interrupt */
	u8 reg_64;
	u32 reg_b0;
	u8 reg_e1;
	irq = pcibios_map_irq(dev, PCI_SLOT(dev->devfn), 1); /* INTA */
	if (!irq)
		return;
	txx9_i8259_irq_setup(irq);
	pci_read_config_byte(dev, 0x64, &reg_64);
	pci_read_config_dword(dev, 0xb0, &reg_b0);
	pci_read_config_byte(dev, 0xe1, &reg_e1);
	/* serial irq control */
	reg_64 = 0xd0;
	/* serial irq pin */
	reg_b0 |= 0x00010000;
	/* ide irq on isa14 */
	reg_e1 &= 0xf0;
	reg_e1 |= 0x0d;
	pci_write_config_byte(dev, 0x64, reg_64);
	pci_write_config_dword(dev, 0xb0, reg_b0);
	pci_write_config_byte(dev, 0xe1, reg_e1);

	smsc_fdc37m81x_init(0x3f0);
	smsc_fdc37m81x_config_beg();
	smsc_fdc37m81x_config_set(SMSC_FDC37M81X_DNUM,
				  SMSC_FDC37M81X_KBD);
	smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT, 1);
	smsc_fdc37m81x_config_set(SMSC_FDC37M81X_INT2, 12);
	smsc_fdc37m81x_config_set(SMSC_FDC37M81X_ACTIVE,
				  1);
	smsc_fdc37m81x_config_end();
}

static void quirk_slc90e66_ide(struct pci_dev *dev)
{
	unsigned char dat;
	int regs[2] = {0x41, 0x43};
	int i;

	/* SMSC SLC90E66 IDE uses irq 14, 15 (default) */
	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 14);
	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &dat);
	pr_info("PCI: %s: IRQ %02x", pci_name(dev), dat);
	/* enable SMSC SLC90E66 IDE */
	for (i = 0; i < ARRAY_SIZE(regs); i++) {
		pci_read_config_byte(dev, regs[i], &dat);
		pci_write_config_byte(dev, regs[i], dat | 0x80);
		pci_read_config_byte(dev, regs[i], &dat);
		pr_cont(" IDETIM%d %02x", i, dat);
	}
	pci_read_config_byte(dev, 0x5c, &dat);
	/*
	 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
	 *
	 * This line of code is intended to provide the user with a work
	 * around solution to the anomalies cited in SMSC's anomaly sheet
	 * entitled, "SLC90E66 Functional Rev.J_0.1 Anomalies"".
	 *
	 * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!!
	 */
	dat |= 0x01;
	pci_write_config_byte(dev, 0x5c, dat);
	pci_read_config_byte(dev, 0x5c, &dat);
	pr_cont(" REG5C %02x\n", dat);
}
#endif /* CONFIG_TOSHIBA_FPCIB0 */

static void tc35815_fixup(struct pci_dev *dev)
{
	/* This device may have PM registers but not they are not supported. */
	if (dev->pm_cap) {
		dev_info(&dev->dev, "PM disabled\n");
		dev->pm_cap = 0;
	}
}

static void final_fixup(struct pci_dev *dev)
{
	unsigned long timeout;
	unsigned char bist;
	int ret;

	/* Do built-in self test */
	ret = pci_read_config_byte(dev, PCI_BIST, &bist);
	if ((ret != PCIBIOS_SUCCESSFUL) || !(bist & PCI_BIST_CAPABLE))
		return;

	pci_set_power_state(dev, PCI_D0);
	pr_info("PCI: %s BIST...", pci_name(dev));
	pci_write_config_byte(dev, PCI_BIST, PCI_BIST_START);
	timeout = jiffies + HZ * 2;	/* timeout after 2 sec */
	do {
		pci_read_config_byte(dev, PCI_BIST, &bist);
		if (time_after(jiffies, timeout))
			break;
	} while (bist & PCI_BIST_START);
	if (bist & (PCI_BIST_CODE_MASK | PCI_BIST_START))
		pr_cont("failed. (0x%x)\n", bist);
	else
		pr_cont("OK.\n");
}

#ifdef CONFIG_TOSHIBA_FPCIB0
#define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_0,
	quirk_slc90e66_bridge);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
	quirk_slc90e66_ide);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1,
	quirk_slc90e66_ide);
#endif
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
			PCI_DEVICE_ID_TOSHIBA_TC35815_NWU, tc35815_fixup);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA_2,
			PCI_DEVICE_ID_TOSHIBA_TC35815_TX4939, tc35815_fixup);
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, final_fixup);
DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, final_fixup);

int pcibios_plat_dev_init(struct pci_dev *dev)
{
	return 0;
}

static int (*txx9_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	return txx9_pci_map_irq(dev, slot, pin);
}

char * (*txx9_board_pcibios_setup)(char *str) __initdata;

char *__init txx9_pcibios_setup(char *str)
{
	if (txx9_board_pcibios_setup && !txx9_board_pcibios_setup(str))
		return NULL;
	if (!strcmp(str, "picmg")) {
		/* PICMG compliant backplane (TOSHIBA JMB-PICMG-ATX
		   (5V or 3.3V), JMB-PICMG-L2 (5V only), etc.) */
		txx9_pci_option |= TXX9_PCI_OPT_PICMG;
		return NULL;
	} else if (!strcmp(str, "nopicmg")) {
		/* non-PICMG compliant backplane (TOSHIBA
		   RBHBK4100,RBHBK4200, Interface PCM-PCM05, etc.) */
		txx9_pci_option &= ~TXX9_PCI_OPT_PICMG;
		return NULL;
	} else if (!strncmp(str, "clk=", 4)) {
		char *val = str + 4;
		txx9_pci_option &= ~TXX9_PCI_OPT_CLK_MASK;
		if (strcmp(val, "33") == 0)
			txx9_pci_option |= TXX9_PCI_OPT_CLK_33;
		else if (strcmp(val, "66") == 0)
			txx9_pci_option |= TXX9_PCI_OPT_CLK_66;
		else /* "auto" */
			txx9_pci_option |= TXX9_PCI_OPT_CLK_AUTO;
		return NULL;
	} else if (!strncmp(str, "err=", 4)) {
		if (!strcmp(str + 4, "panic"))
			txx9_pci_err_action = TXX9_PCI_ERR_PANIC;
		else if (!strcmp(str + 4, "ignore"))
			txx9_pci_err_action = TXX9_PCI_ERR_IGNORE;
		return NULL;
	}

	txx9_pci_map_irq = txx9_board_vec->pci_map_irq;

	return str;
}
