/*
 * 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/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(KERN_WARNING
		"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 *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(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);
}
