/*
 * arch/arm/mach-ixp2000/pci.c
 *
 * PCI routines for IXDP2400/IXDP2800 boards
 *
 * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
 * Maintained by: Deepak Saxena <dsaxena@plexity.net>
 *
 * Copyright 2002 Intel Corp.
 * Copyright (C) 2003-2004 MontaVista Software, Inc.
 *
 *  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/system.h>
#include <mach/hardware.h>

#include <asm/mach/pci.h>

static volatile int pci_master_aborts = 0;

static int clear_master_aborts(void);

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

	if (PCI_SLOT(devfn) > 7)
		return 0;

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

	/*
	 * For top bus, generate type 0, else type 1
	 */
	if (!bus_nr) {
		/* only bits[23:16] are used for IDSEL */
		paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE
				    | (1 << (PCI_SLOT(devfn) + 16))
				    | (PCI_FUNC(devfn) << 8) | where);
	} else {
		paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE 
				    | (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,
};


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

	n = where % 4;

	addr = ixp2000_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 checks by calling clear_master_aborts() b/c the
 * assumption is that the caller did a read first to make sure a device
 * exists.
 */
int ixp2000_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 = ixp2000_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;
}


static struct pci_ops ixp2000_pci_ops = {
	.read	= ixp2000_pci_read_config,
	.write	= ixp2000_pci_write_config
};

struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
{
	return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops,
				 sysdata, &sysdata->resources);
}


int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{

	volatile u32 temp;
	unsigned long flags;

	pci_master_aborts = 1;

	local_irq_save(flags);
	temp = *(IXP2000_PCI_CONTROL);
	if (temp & ((1 << 8) | (1 << 5))) {
		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
	}

	temp = *(IXP2000_PCI_CMDSTAT);
	if (temp & (1 << 29)) {
		while (temp & (1 << 29)) {	
			ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
			temp = *(IXP2000_PCI_CMDSTAT);
		}
	}
	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;
	unsigned long flags;

	local_irq_save(flags);
	temp = *(IXP2000_PCI_CONTROL);
	if (temp & ((1 << 8) | (1 << 5))) {
		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
	}

	temp = *(IXP2000_PCI_CMDSTAT);
	if (temp & (1 << 29)) {
		while (temp & (1 << 29)) {
			ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
			temp = *(IXP2000_PCI_CMDSTAT);
		}
	}
	local_irq_restore(flags);

	return 0;
}

void __init
ixp2000_pci_preinit(void)
{
	pci_set_flags(0);

	pcibios_min_io = 0;
	pcibios_min_mem = 0;

#ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
	/*
	 * Configure the PCI unit to properly byteswap I/O transactions,
	 * and verify that it worked.
	 */
	ixp2000_reg_write(IXP2000_PCI_CONTROL,
			  (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE));

	if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0)
		panic("IXP2000: PCI I/O is broken on this ixp model, and "
			"the needed workaround has not been configured in");
#endif

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


/*
 * IXP2000 systems often have large resource requirements, so we just
 * use our own resource space.
 */
static struct resource ixp2000_pci_mem_space = {
	.start	= 0xe0000000,
	.end	= 0xffffffff,
	.flags	= IORESOURCE_MEM,
	.name	= "PCI Mem Space"
};

static struct resource ixp2000_pci_io_space = {
	.start	= 0x00010000,
	.end	= 0x0001ffff,
	.flags	= IORESOURCE_IO,
	.name	= "PCI I/O Space"
};

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

	pci_add_resource(&sys->resources, &ixp2000_pci_io_space);
	pci_add_resource(&sys->resources, &ixp2000_pci_mem_space);

	return 1;
}

