/*
 * Workaround for device erratum PCI 9.
 * See Motorola's "XPC826xA Family Device Errata Reference."
 * The erratum applies to all 8260 family Hip4 processors.  It is scheduled 
 * to be fixed in HiP4 Rev C.  Erratum PCI 9 states that a simultaneous PCI 
 * inbound write transaction and PCI outbound read transaction can result in a 
 * bus deadlock.  The suggested workaround is to use the IDMA controller to 
 * perform all reads from PCI configuration, memory, and I/O space.
 *
 * Author:  andy_lowe@mvista.com
 *
 * 2003 (c) MontaVista Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 */
#include <linux/kernel.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/types.h>
#include <linux/string.h>

#include <asm/io.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/byteorder.h>
#include <asm/mpc8260.h>
#include <asm/immap_cpm2.h>
#include <asm/cpm2.h>

#include "m82xx_pci.h"

#ifdef CONFIG_8260_PCI9
/*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */

#define IDMA_XFER_BUF_SIZE 64	/* size of the IDMA transfer buffer */

/* define a structure for the IDMA dpram usage */
typedef struct idma_dpram_s {
	idma_t pram;				/* IDMA parameter RAM */
	u_char xfer_buf[IDMA_XFER_BUF_SIZE];	/* IDMA transfer buffer */
	idma_bd_t bd;				/* buffer descriptor */
} idma_dpram_t;

/* define offsets relative to start of IDMA dpram */
#define IDMA_XFER_BUF_OFFSET (sizeof(idma_t))
#define IDMA_BD_OFFSET (sizeof(idma_t) + IDMA_XFER_BUF_SIZE)

/* define globals */
static volatile idma_dpram_t *idma_dpram;

/* Exactly one of CONFIG_8260_PCI9_IDMAn must be defined, 
 * where n is 1, 2, 3, or 4.  This selects the IDMA channel used for 
 * the PCI9 workaround.
 */
#ifdef CONFIG_8260_PCI9_IDMA1
#define IDMA_CHAN 0
#define PROFF_IDMA PROFF_IDMA1_BASE
#define IDMA_PAGE CPM_CR_IDMA1_PAGE
#define IDMA_SBLOCK CPM_CR_IDMA1_SBLOCK
#endif
#ifdef CONFIG_8260_PCI9_IDMA2
#define IDMA_CHAN 1
#define PROFF_IDMA PROFF_IDMA2_BASE
#define IDMA_PAGE CPM_CR_IDMA2_PAGE
#define IDMA_SBLOCK CPM_CR_IDMA2_SBLOCK
#endif
#ifdef CONFIG_8260_PCI9_IDMA3
#define IDMA_CHAN 2
#define PROFF_IDMA PROFF_IDMA3_BASE
#define IDMA_PAGE CPM_CR_IDMA3_PAGE
#define IDMA_SBLOCK CPM_CR_IDMA3_SBLOCK
#endif
#ifdef CONFIG_8260_PCI9_IDMA4
#define IDMA_CHAN 3
#define PROFF_IDMA PROFF_IDMA4_BASE
#define IDMA_PAGE CPM_CR_IDMA4_PAGE
#define IDMA_SBLOCK CPM_CR_IDMA4_SBLOCK
#endif

void idma_pci9_init(void)
{
	uint dpram_offset;
	volatile idma_t *pram;
	volatile im_idma_t *idma_reg;
	volatile cpm2_map_t *immap = cpm2_immr;

	/* allocate IDMA dpram */
	dpram_offset = cpm_dpalloc(sizeof(idma_dpram_t), 64);
	idma_dpram = cpm_dpram_addr(dpram_offset); 

	/* initialize the IDMA parameter RAM */
	memset((void *)idma_dpram, 0, sizeof(idma_dpram_t));
	pram = &idma_dpram->pram;
	pram->ibase = dpram_offset + IDMA_BD_OFFSET;
	pram->dpr_buf = dpram_offset + IDMA_XFER_BUF_OFFSET;
	pram->ss_max = 32;
	pram->dts = 32;

	/* initialize the IDMA_BASE pointer to the IDMA parameter RAM */
	*((ushort *) &immap->im_dprambase[PROFF_IDMA]) = dpram_offset;

	/* initialize the IDMA registers */
	idma_reg = (volatile im_idma_t *) &immap->im_sdma.sdma_idsr1;
	idma_reg[IDMA_CHAN].idmr = 0;		/* mask all IDMA interrupts */
	idma_reg[IDMA_CHAN].idsr = 0xff;	/* clear all event flags */

	printk("<4>Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n",
		IDMA_CHAN + 1);

	return;
}

/* Use the IDMA controller to transfer data from I/O memory to local RAM.
 * The src address must be a physical address suitable for use by the DMA 
 * controller with no translation.  The dst address must be a kernel virtual 
 * address.  The dst address is translated to a physical address via 
 * virt_to_phys().
 * The sinc argument specifies whether or not the source address is incremented
 * by the DMA controller.  The source address is incremented if and only if sinc
 * is non-zero.  The destination address is always incremented since the 
 * destination is always host RAM.
 */
static void 
idma_pci9_read(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
{
	unsigned long flags;
	volatile idma_t *pram = &idma_dpram->pram;
	volatile idma_bd_t *bd = &idma_dpram->bd;
	volatile cpm2_map_t *immap = cpm2_immr;

	local_irq_save(flags);

	/* initialize IDMA parameter RAM for this transfer */
	if (sinc)
		pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
			  | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
	else
		pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_DINC 
			  | IDMA_DCM_SD_MEM2MEM;
	pram->ibdptr = pram->ibase;
	pram->sts = unit_size;
	pram->istate = 0;

	/* initialize the buffer descriptor */
	bd->dst = virt_to_phys(dst);
	bd->src = (uint) src;
	bd->len = bytes;
	bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL
		  | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB;

	/* issue the START_IDMA command to the CP */
	while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
	immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0,
					 CPM_CR_START_IDMA) | CPM_CR_FLG;
	while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);

	/* wait for transfer to complete */
	while(bd->flags & IDMA_BD_V);

	local_irq_restore(flags);

	return;
}

/* Use the IDMA controller to transfer data from I/O memory to local RAM.
 * The dst address must be a physical address suitable for use by the DMA 
 * controller with no translation.  The src address must be a kernel virtual 
 * address.  The src address is translated to a physical address via 
 * virt_to_phys().
 * The dinc argument specifies whether or not the dest address is incremented
 * by the DMA controller.  The source address is incremented if and only if sinc
 * is non-zero.  The source address is always incremented since the 
 * source is always host RAM.
 */
static void 
idma_pci9_write(u8 *dst, u8 *src, int bytes, int unit_size, int dinc)
{
	unsigned long flags;
	volatile idma_t *pram = &idma_dpram->pram;
	volatile idma_bd_t *bd = &idma_dpram->bd;
	volatile cpm2_map_t *immap = cpm2_immr;

	local_irq_save(flags);

	/* initialize IDMA parameter RAM for this transfer */
	if (dinc)
		pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC
			  | IDMA_DCM_DINC | IDMA_DCM_SD_MEM2MEM;
	else
		pram->dcm = IDMA_DCM_DMA_WRAP_64 | IDMA_DCM_SINC 
			  | IDMA_DCM_SD_MEM2MEM;
	pram->ibdptr = pram->ibase;
	pram->sts = unit_size;
	pram->istate = 0;

	/* initialize the buffer descriptor */
	bd->dst = (uint) dst;
	bd->src = virt_to_phys(src);
	bd->len = bytes;
	bd->flags = IDMA_BD_V | IDMA_BD_W | IDMA_BD_I | IDMA_BD_L | IDMA_BD_DGBL
		  | IDMA_BD_DBO_BE | IDMA_BD_SBO_BE | IDMA_BD_SDTB;

	/* issue the START_IDMA command to the CP */
	while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);
	immap->im_cpm.cp_cpcr = mk_cr_cmd(IDMA_PAGE, IDMA_SBLOCK, 0,
					 CPM_CR_START_IDMA) | CPM_CR_FLG;
	while (immap->im_cpm.cp_cpcr & CPM_CR_FLG);

	/* wait for transfer to complete */
	while(bd->flags & IDMA_BD_V);

	local_irq_restore(flags);

	return;
}

/* Same as idma_pci9_read, but 16-bit little-endian byte swapping is performed
 * if the unit_size is 2, and 32-bit little-endian byte swapping is performed if
 * the unit_size is 4.
 */
static void 
idma_pci9_read_le(u8 *dst, u8 *src, int bytes, int unit_size, int sinc)
{
	int i;
	u8 *p;

	idma_pci9_read(dst, src, bytes, unit_size, sinc);
	switch(unit_size) {
		case 2:
			for (i = 0, p = dst; i < bytes; i += 2, p += 2)
				swab16s((u16 *) p);
			break;
		case 4:
			for (i = 0, p = dst; i < bytes; i += 4, p += 4)
				swab32s((u32 *) p);
			break;
		default:
			break;
	}
}
EXPORT_SYMBOL(idma_pci9_init);
EXPORT_SYMBOL(idma_pci9_read);
EXPORT_SYMBOL(idma_pci9_read_le);

static inline int is_pci_mem(unsigned long addr)
{
	if (addr >= M82xx_PCI_LOWER_MMIO &&
		addr <= M82xx_PCI_UPPER_MMIO)
		return 1;
	if (addr >= M82xx_PCI_LOWER_MEM &&
		addr <= M82xx_PCI_UPPER_MEM)
		return 1;
	return 0;
}

#define is_pci_mem(pa) ( (pa > 0x80000000) && (pa < 0xc0000000))
int readb(volatile unsigned char *addr)
{
	u8 val;
	unsigned long pa = iopa((unsigned long) addr);

	if (!is_pci_mem(pa))
		return in_8(addr);

	idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
	return val;
}

int readw(volatile unsigned short *addr)
{
	u16 val;
	unsigned long pa = iopa((unsigned long) addr);

	if (!is_pci_mem(pa))
		return in_le16(addr);

	idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
	return swab16(val);
}

unsigned readl(volatile unsigned *addr)
{
	u32 val;
	unsigned long pa = iopa((unsigned long) addr);

	if (!is_pci_mem(pa))
		return in_le32(addr);

	idma_pci9_read((u8 *)&val, (u8 *)pa, sizeof(val), sizeof(val), 0);
	return swab32(val);
}

int inb(unsigned port)
{
	u8 val;
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
	return val;
}

int inw(unsigned port)
{
	u16 val;
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
	return swab16(val);
}

unsigned inl(unsigned port)
{
	u32 val;
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)&val, (u8 *)addr, sizeof(val), sizeof(val), 0);
	return swab32(val);
}

void insb(unsigned port, void *buf, int ns)
{
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u8), sizeof(u8), 0);
}

void insw(unsigned port, void *buf, int ns)
{
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
}

void insl(unsigned port, void *buf, int nl)
{
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
}

void insw_ns(unsigned port, void *buf, int ns)
{
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)buf, (u8 *)addr, ns*sizeof(u16), sizeof(u16), 0);
}

void insl_ns(unsigned port, void *buf, int nl)
{
	u8 *addr = (u8 *)(port + _IO_BASE);

	idma_pci9_read((u8 *)buf, (u8 *)addr, nl*sizeof(u32), sizeof(u32), 0);
}

void *memcpy_fromio(void *dest, unsigned long src, size_t count)
{
	unsigned long pa = iopa((unsigned long) src);

	if (is_pci_mem(pa))
		idma_pci9_read((u8 *)dest, (u8 *)pa, count, 32, 1);
	else
		memcpy(dest, (void *)src, count);
	return dest;
}

EXPORT_SYMBOL(readb);
EXPORT_SYMBOL(readw);
EXPORT_SYMBOL(readl);
EXPORT_SYMBOL(inb);
EXPORT_SYMBOL(inw);
EXPORT_SYMBOL(inl);
EXPORT_SYMBOL(insb);
EXPORT_SYMBOL(insw);
EXPORT_SYMBOL(insl);
EXPORT_SYMBOL(insw_ns);
EXPORT_SYMBOL(insl_ns);
EXPORT_SYMBOL(memcpy_fromio);

#endif	/* ifdef CONFIG_8260_PCI9 */

/* Indirect PCI routines adapted from arch/ppc/kernel/indirect_pci.c.
 * Copyright (C) 1998 Gabriel Paubert.
 */
#ifndef CONFIG_8260_PCI9
#define cfg_read(val, addr, type, op)	*val = op((type)(addr))
#else
#define cfg_read(val, addr, type, op) \
	idma_pci9_read_le((u8*)(val),(u8*)(addr),sizeof(*(val)),sizeof(*(val)),0)
#endif

#define cfg_write(val, addr, type, op)	op((type *)(addr), (val))

static int indirect_write_config(struct pci_bus *pbus, unsigned int devfn, int where,
			 int size, u32 value)
{
	struct pci_controller *hose = pbus->sysdata;
	u8 cfg_type = 0;
	if (ppc_md.pci_exclude_device)
		if (ppc_md.pci_exclude_device(pbus->number, devfn))
			return PCIBIOS_DEVICE_NOT_FOUND;

	if (hose->set_cfg_type)
		if (pbus->number != hose->first_busno)
			cfg_type = 1;

	out_be32(hose->cfg_addr,
		 (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
		 | ((pbus->number - hose->bus_offset) << 8) | 0x80);

	switch (size)
	{
		case 1:
			cfg_write(value, hose->cfg_data + (where & 3), u8, out_8);
			break;
		case 2:
			cfg_write(value, hose->cfg_data + (where & 2), u16, out_le16);
			break;
		case 4:
			cfg_write(value, hose->cfg_data + (where & 0), u32, out_le32);
			break;
	}		
	return PCIBIOS_SUCCESSFUL;
}

static int indirect_read_config(struct pci_bus *pbus, unsigned int devfn, int where,
			 int size, u32 *value)
{
	struct pci_controller *hose = pbus->sysdata;
	u8 cfg_type = 0;
	if (ppc_md.pci_exclude_device)
		if (ppc_md.pci_exclude_device(pbus->number, devfn))
			return PCIBIOS_DEVICE_NOT_FOUND;

	if (hose->set_cfg_type)
		if (pbus->number != hose->first_busno)
			cfg_type = 1;

	out_be32(hose->cfg_addr,
		 (((where & 0xfc) | cfg_type) << 24) | (devfn << 16)
		 | ((pbus->number - hose->bus_offset) << 8) | 0x80);

	switch (size)
	{
		case 1:
			cfg_read(value, hose->cfg_data + (where & 3), u8 *, in_8);
			break;
		case 2:
			cfg_read(value, hose->cfg_data + (where & 2), u16 *, in_le16);
			break;
		case 4:
			cfg_read(value, hose->cfg_data + (where & 0), u32 *, in_le32);
			break;
	}		
	return PCIBIOS_SUCCESSFUL;
}

static struct pci_ops indirect_pci_ops =
{
	.read = indirect_read_config,
	.write = indirect_write_config,
};

void
setup_m8260_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
{
	hose->ops = &indirect_pci_ops;
	hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4);
	hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4);
}
