/*
 * Copyright 2001 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *              ahennessy@mvista.com
 *
 * Copyright (C) 2000-2001 Toshiba Corporation
 * Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
 *
 * Based on arch/mips/ddb5xxx/ddb5477/pci_ops.c
 *
 *     Define the pci_ops for TX3927.
 *
 * Much of the code is derived from the original DDB5074 port by
 * Geert Uytterhoeven <geert@sonycom.com>
 *
 *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>

#include <asm/addrspace.h>
#include <asm/txx9/tx3927.h>

static inline int mkaddr(unsigned char bus, unsigned char dev_fn,
	unsigned char where)
{
	if (bus == 0 && dev_fn >= PCI_DEVFN(TX3927_PCIC_MAX_DEVNU, 0))
		return PCIBIOS_DEVICE_NOT_FOUND;

	tx3927_pcicptr->ica = ((bus & 0xff) << 0x10) |
	                      ((dev_fn & 0xff) << 0x08) |
	                      (where & 0xfc);

	/* clear M_ABORT and Disable M_ABORT Int. */
	tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
	tx3927_pcicptr->pcistatim &= ~PCI_STATUS_REC_MASTER_ABORT;

	return PCIBIOS_SUCCESSFUL;
}

static inline int check_abort(void)
{
	if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
		tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
		tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
		return PCIBIOS_DEVICE_NOT_FOUND;

	return PCIBIOS_SUCCESSFUL;
}

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

	ret = mkaddr(bus->number, devfn, where);
	if (ret)
		return ret;

	switch (size) {
	case 1:
		*val = *(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3));
		break;

	case 2:
		*val = le16_to_cpu(*(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)));
		break;

	case 4:
		*val = le32_to_cpu(tx3927_pcicptr->icd);
		break;
	}

	return check_abort();
}

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

	ret = mkaddr(bus->number, devfn, where);
	if (ret)
		return ret;

	switch (size) {
	case 1:
		*(volatile u8 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 3)) = val;
		break;

	case 2:
		*(volatile u16 *) ((unsigned long) & tx3927_pcicptr->icd | (where & 2)) =
	    cpu_to_le16(val);
		break;

	case 4:
		tx3927_pcicptr->icd = cpu_to_le32(val);
	}

	if (tx3927_pcicptr->pcistat & PCI_STATUS_REC_MASTER_ABORT)
		tx3927_pcicptr->pcistat |= PCI_STATUS_REC_MASTER_ABORT;
		tx3927_pcicptr->pcistatim |= PCI_STATUS_REC_MASTER_ABORT;
		return PCIBIOS_DEVICE_NOT_FOUND;

	return check_abort();
}

static struct pci_ops tx3927_pci_ops = {
	.read = tx3927_pci_read_config,
	.write = tx3927_pci_write_config,
};

void __init tx3927_pcic_setup(struct pci_controller *channel,
			      unsigned long sdram_size, int extarb)
{
	unsigned long flags;
	unsigned long io_base =
		channel->io_resource->start + mips_io_port_base - IO_BASE;
	unsigned long io_size =
		channel->io_resource->end - channel->io_resource->start;
	unsigned long io_pciaddr =
		channel->io_resource->start - channel->io_offset;
	unsigned long mem_base =
		channel->mem_resource->start;
	unsigned long mem_size =
		channel->mem_resource->end - channel->mem_resource->start;
	unsigned long mem_pciaddr =
		channel->mem_resource->start - channel->mem_offset;

	printk(KERN_INFO "TX3927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s",
	       tx3927_pcicptr->did, tx3927_pcicptr->vid,
	       tx3927_pcicptr->rid,
	       extarb ? "External" : "Internal");
	channel->pci_ops = &tx3927_pci_ops;

	local_irq_save(flags);
	/* Disable External PCI Config. Access */
	tx3927_pcicptr->lbc = TX3927_PCIC_LBC_EPCAD;
#ifdef __BIG_ENDIAN
	tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_IBSE |
		TX3927_PCIC_LBC_TIBSE |
		TX3927_PCIC_LBC_TMFBSE | TX3927_PCIC_LBC_MSDSE;
#endif
	/* LB->PCI mappings */
	tx3927_pcicptr->iomas = ~(io_size - 1);
	tx3927_pcicptr->ilbioma = io_base;
	tx3927_pcicptr->ipbioma = io_pciaddr;
	tx3927_pcicptr->mmas = ~(mem_size - 1);
	tx3927_pcicptr->ilbmma = mem_base;
	tx3927_pcicptr->ipbmma = mem_pciaddr;
	/* PCI->LB mappings */
	tx3927_pcicptr->iobas = 0xffffffff;
	tx3927_pcicptr->ioba = 0;
	tx3927_pcicptr->tlbioma = 0;
	tx3927_pcicptr->mbas = ~(sdram_size - 1);
	tx3927_pcicptr->mba = 0;
	tx3927_pcicptr->tlbmma = 0;
	/* Enable Direct mapping Address Space Decoder */
	tx3927_pcicptr->lbc |= TX3927_PCIC_LBC_ILMDE | TX3927_PCIC_LBC_ILIDE;

	/* Clear All Local Bus Status */
	tx3927_pcicptr->lbstat = TX3927_PCIC_LBIM_ALL;
	/* Enable All Local Bus Interrupts */
	tx3927_pcicptr->lbim = TX3927_PCIC_LBIM_ALL;
	/* Clear All PCI Status Error */
	tx3927_pcicptr->pcistat = TX3927_PCIC_PCISTATIM_ALL;
	/* Enable All PCI Status Error Interrupts */
	tx3927_pcicptr->pcistatim = TX3927_PCIC_PCISTATIM_ALL;

	/* PCIC Int => IRC IRQ10 */
	tx3927_pcicptr->il = TX3927_IR_PCI;
	/* Target Control (per errata) */
	tx3927_pcicptr->tc = TX3927_PCIC_TC_OF8E | TX3927_PCIC_TC_IF8E;

	/* Enable Bus Arbiter */
	if (!extarb)
		tx3927_pcicptr->pbapmc = TX3927_PCIC_PBAPMC_PBAEN;

	tx3927_pcicptr->pcicmd = PCI_COMMAND_MASTER |
		PCI_COMMAND_MEMORY |
		PCI_COMMAND_IO |
		PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
	local_irq_restore(flags);
}
