/*
 * arch/arm/mach-ixp23xx/pci.c
 *
 * PCI routines for IXP23XX based systems
 *
 * Copyright (c) 2005 MontaVista Software, Inc.
 *
 * based on original code:
 *
 * Author: Naeem Afzal <naeem.m.afzal@intel.com>
 * Copyright 2002-2005 Intel Corp.
 *
 * 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.
 */

#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/io.h>

#include <asm/irq.h>
#include <asm/sizes.h>
#include <asm/system.h>
#include <asm/mach/pci.h>
#include <mach/hardware.h>

extern int (*external_fault) (unsigned long, struct pt_regs *);

static volatile int pci_master_aborts = 0;

#ifdef DEBUG
#define DBG(x...)	printk(x)
#else
#define DBG(x...)
#endif

int clear_master_aborts(void);

static u32
*ixp23xx_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
{
	u32 *paddress;

	/*
	 * Must be dword aligned
	 */
	where &= ~3;

	/*
	 * For top bus, generate type 0, else type 1
	 */
	if (!bus_nr) {
		if (PCI_SLOT(devfn) >= 8)
			return 0;

		paddress = (u32 *) (IXP23XX_PCI_CFG0_VIRT
				    | (1 << (PCI_SLOT(devfn) + 16))
				    | (PCI_FUNC(devfn) << 8) | where);
	} else {
		paddress = (u32 *) (IXP23XX_PCI_CFG1_VIRT
				    | (bus_nr << 16)
				    | (PCI_SLOT(devfn) << 11)
				    | (PCI_FUNC(devfn) << 8) | where);
	}

	return paddress;
}

/*
 * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
 * 0 and 3 are not valid indexes...
 */
static u32 bytemask[] = {
	/*0*/	0,
	/*1*/	0xff,
	/*2*/	0xffff,
	/*3*/	0,
	/*4*/	0xffffffff,
};

static int ixp23xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
				int where, int size, u32 *value)
{
	u32 n;
	u32 *addr;

	n = where % 4;

	DBG("In config_read(%d) %d from dev %d:%d:%d\n", size, where,
		bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));

	addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
	if (!addr)
		return PCIBIOS_DEVICE_NOT_FOUND;

	pci_master_aborts = 0;
	*value = (*addr >> (8*n)) & bytemask[size];
	if (pci_master_aborts) {
			pci_master_aborts = 0;
			*value = 0xffffffff;
			return PCIBIOS_DEVICE_NOT_FOUND;
		}

	return PCIBIOS_SUCCESSFUL;
}

/*
 * We don't do error checking on the address for writes.
 * It's assumed that the user checked for the device existing first
 * by doing a read first.
 */
static int ixp23xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
					int where, int size, u32 value)
{
	u32 mask;
	u32 *addr;
	u32 temp;

	mask = ~(bytemask[size] << ((where % 0x4) * 8));
	addr = ixp23xx_pci_config_addr(bus->number, devfn, where);
	if (!addr)
		return PCIBIOS_DEVICE_NOT_FOUND;
	temp = (u32) (value) << ((where % 0x4) * 8);
	*addr = (*addr & mask) | temp;

	clear_master_aborts();

	return PCIBIOS_SUCCESSFUL;
}

struct pci_ops ixp23xx_pci_ops = {
	.read	= ixp23xx_pci_read_config,
	.write	= ixp23xx_pci_write_config,
};

struct pci_bus *ixp23xx_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
	return pci_scan_bus(sysdata->busnr, &ixp23xx_pci_ops, sysdata);
}

int ixp23xx_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
	volatile unsigned long temp;
	unsigned long flags;

	pci_master_aborts = 1;

	local_irq_save(flags);
	temp = *IXP23XX_PCI_CONTROL;

	/*
	 * master abort and cmd tgt err
	 */
	if (temp & ((1 << 8) | (1 << 5)))
		*IXP23XX_PCI_CONTROL = temp;

	temp = *IXP23XX_PCI_CMDSTAT;

	if (temp & (1 << 29))
		*IXP23XX_PCI_CMDSTAT = temp;
	local_irq_restore(flags);

	/*
	 * If it was an imprecise abort, then we need to correct the
	 * return address to be _after_ the instruction.
	 */
	if (fsr & (1 << 10))
		regs->ARM_pc += 4;

	return 0;
}

int clear_master_aborts(void)
{
	volatile u32 temp;

	temp = *IXP23XX_PCI_CONTROL;

	/*
	 * master abort and cmd tgt err
	 */
	if (temp & ((1 << 8) | (1 << 5)))
		*IXP23XX_PCI_CONTROL = temp;

	temp = *IXP23XX_PCI_CMDSTAT;

	if (temp & (1 << 29))
		*IXP23XX_PCI_CMDSTAT = temp;

	return 0;
}

static void __init ixp23xx_pci_common_init(void)
{
#ifdef __ARMEB__
	*IXP23XX_PCI_CONTROL |= 0x20000;	/* set I/O swapping */
#endif
	/*
	 * ADDR_31 needs to be clear for PCI memory access to CPP memory
	 */
	*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_ADDR_31;
	*IXP23XX_CPP2XSI_CURR_XFER_REG3 |= IXP23XX_CPP2XSI_PSH_OFF;

	/*
	 * Select correct memory for PCI inbound transactions
	 */
	if (ixp23xx_cpp_boot()) {
		*IXP23XX_PCI_CPP_ADDR_BITS &= ~(1 << 1);
	} else {
		*IXP23XX_PCI_CPP_ADDR_BITS |= (1 << 1);

		/*
		 * Enable coherency on A2 silicon.
		 */
		if (arch_is_coherent())
			*IXP23XX_CPP2XSI_CURR_XFER_REG3 &= ~IXP23XX_CPP2XSI_COH_OFF;
	}
}

void __init ixp23xx_pci_preinit(void)
{
	pcibios_min_io = 0;
	pcibios_min_mem = 0xe0000000;

	pci_set_flags(0);

	ixp23xx_pci_common_init();

	hook_fault_code(16+6, ixp23xx_pci_abort_handler, SIGBUS, 0,
			"PCI config cycle to non-existent device");

	*IXP23XX_PCI_ADDR_EXT = 0x0000e000;
}

/*
 * Prevent PCI layer from seeing the inbound host-bridge resources
 */
static void __devinit pci_fixup_ixp23xx(struct pci_dev *dev)
{
	int i;

	dev->class &= 0xff;
	dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
		dev->resource[i].start = 0;
		dev->resource[i].end   = 0;
		dev->resource[i].flags = 0;
	}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9002, pci_fixup_ixp23xx);

/*
 * IXP2300 systems often have large resource requirements, so we just
 * use our own resource space.
 */
static struct resource ixp23xx_pci_mem_space = {
	.start	= IXP23XX_PCI_MEM_START,
	.end	= IXP23XX_PCI_MEM_START + IXP23XX_PCI_MEM_SIZE - 1,
	.flags	= IORESOURCE_MEM,
	.name	= "PCI Mem Space"
};

static struct resource ixp23xx_pci_io_space = {
	.start	= 0x00000100,
	.end	= 0x01ffffff,
	.flags	= IORESOURCE_IO,
	.name	= "PCI I/O Space"
};

int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys)
{
	if (nr >= 1)
		return 0;

	sys->resource[0] = &ixp23xx_pci_io_space;
	sys->resource[1] = &ixp23xx_pci_mem_space;
	sys->resource[2] = NULL;

	return 1;
}

void __init ixp23xx_pci_slave_init(void)
{
	ixp23xx_pci_common_init();
}
