/*
 * IXP PCI Init
 * (C) Copyright 2004 eslab.whut.edu.cn
 * Yue Hu(huyue_whut@yahoo.com.cn), Ligong Xue(lgxue@hotmail.com)
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */


#include <common.h>

#ifdef CONFIG_PCI

#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#include <asm/arch/ixp425.h>
#include <asm/arch/ixp425pci.h>

static void non_prefetch_read (unsigned int addr, unsigned int cmd,
			       unsigned int *data);
static void non_prefetch_write (unsigned int addr, unsigned int cmd,
				unsigned int data);
static void configure_pins (void);
static void sys_pci_gpio_clock_config (void);
static void pci_bus_scan (void);
static int pci_device_exists (unsigned int deviceNo);
static void sys_pci_bar_info_get (unsigned int devnum, unsigned int bus,
				  unsigned int dev, unsigned int func);
static void sys_pci_device_bars_write (void);
static void calc_bars (PciBar * Bars[], unsigned int nBars,
		       unsigned int startAddr);

#define PCI_MEMORY_BUS		0x00000000
#define PCI_MEMORY_PHY		0x48000000
#define PCI_MEMORY_SIZE		0x04000000

#define PCI_MEM_BUS		0x40000000
#define PCI_MEM_PHY		0x00000000
#define PCI_MEM_SIZE		0x04000000

#define	PCI_IO_BUS		0x40000000
#define PCI_IO_PHY		0x50000000
#define PCI_IO_SIZE		0x10000000

struct pci_controller hose;

unsigned int nDevices;
unsigned int nMBars;
unsigned int nIOBars;
PciBar *memBars[IXP425_PCI_MAX_BAR];
PciBar *ioBars[IXP425_PCI_MAX_BAR];
PciDevice devices[IXP425_PCI_MAX_FUNC_ON_BUS];

int pci_read_config_dword (pci_dev_t dev, int where, unsigned int *val)
{
	unsigned int retval;
	unsigned int addr;

	/*address bits 31:28 specify the device 10:8 specify the function */
	/*Set the address to be read */
	addr = BIT ((31 - dev)) | (where & ~3);
	non_prefetch_read (addr, NP_CMD_CONFIGREAD, &retval);

	*val = retval;

	return (OK);
}

int pci_read_config_word (pci_dev_t dev, int where, unsigned short *val)
{
	unsigned int n;
	unsigned int retval;
	unsigned int addr;
	unsigned int byteEnables;

	n = where % 4;
	/*byte enables are 4 bits active low, the position of each
	   bit maps to the byte that it enables */
	byteEnables =
		(~(BIT (n) | BIT ((n + 1)))) &
		IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
	byteEnables = byteEnables << PCI_NP_CBE_BESL;
	/*address bits 31:28 specify the device 10:8 specify the function */
	/*Set the address to be read */
	addr = BIT ((31 - dev)) | (where & ~3);
	non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);

	/*Pick out the word we are interested in */
	*val = (retval >> (8 * n));

	return (OK);
}

int pci_read_config_byte (pci_dev_t dev, int where, unsigned char *val)
{
	unsigned int retval;
	unsigned int n;
	unsigned int byteEnables;
	unsigned int addr;

	n = where % 4;
	/*byte enables are 4 bits, active low, the position of each
	   bit maps to the byte that it enables */
	byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
	byteEnables = byteEnables << PCI_NP_CBE_BESL;

	/*address bits 31:28 specify the device, 10:8 specify the function */
	/*Set the address to be read */
	addr = BIT ((31 - dev)) | (where & ~3);
	non_prefetch_read (addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
	/*Pick out the byte we are interested in */
	*val = (retval >> (8 * n));

	return (OK);
}

int pci_write_config_byte (pci_dev_t dev, int where, unsigned char val)
{
	unsigned int addr;
	unsigned int byteEnables;
	unsigned int n;
	unsigned int ldata;

	n = where % 4;
	/*byte enables are 4 bits active low, the position of each
	   bit maps to the byte that it enables */
	byteEnables = (~BIT (n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
	byteEnables = byteEnables << PCI_NP_CBE_BESL;
	ldata = val << (8 * n);
	/*address bits 31:28 specify the device 10:8 specify the function */
	/*Set the address to be written */
	addr = BIT ((31 - dev)) | (where & ~3);
	non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);

	return (OK);
}

int pci_write_config_word (pci_dev_t dev, int where, unsigned short val)
{
	unsigned int addr;
	unsigned int byteEnables;
	unsigned int n;
	unsigned int ldata;

	n = where % 4;
	/*byte enables are 4 bits active low, the position of each
	   bit maps to the byte that it enables */
	byteEnables =
		(~(BIT (n) | BIT ((n + 1)))) &
		IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
	byteEnables = byteEnables << PCI_NP_CBE_BESL;
	ldata = val << (8 * n);
	/*address bits 31:28 specify the device 10:8 specify the function */
	/*Set the address to be written */
	addr = BIT (31 - dev) | (where & ~3);
	non_prefetch_write (addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);

	return (OK);
}

int pci_write_config_dword (pci_dev_t dev, int where, unsigned int val)
{
	unsigned int addr;

	/*address bits 31:28 specify the device 10:8 specify the function */
	/*Set the address to be written */
	addr = BIT (31 - dev) | (where & ~3);
	non_prefetch_write (addr, NP_CMD_CONFIGWRITE, val);

	return (OK);
}

void non_prefetch_read (unsigned int addr,
			unsigned int cmd, unsigned int *data)
{
	REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);

	/*set up and execute the read */
	REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd);

	/*The result of the read is now in np_rdata */
	REG_READ (PCI_CSR_BASE, PCI_NP_RDATA_OFFSET, *data);

	return;
}

void non_prefetch_write (unsigned int addr,
			 unsigned int cmd, unsigned int data)
{

	REG_WRITE (PCI_CSR_BASE, PCI_NP_AD_OFFSET, addr);
	/*set up the write */
	REG_WRITE (PCI_CSR_BASE, PCI_NP_CBE_OFFSET, cmd);
	/*Execute the write by writing to NP_WDATA */
	REG_WRITE (PCI_CSR_BASE, PCI_NP_WDATA_OFFSET, data);

	return;
}

/*
 * PCI controller config registers are accessed through these functions
 * i.e. these allow us to set up our own BARs etc.
 */
void crp_read (unsigned int offset, unsigned int *data)
{
	REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET, offset);
	REG_READ (PCI_CSR_BASE, PCI_CRP_RDATA_OFFSET, *data);
}

void crp_write (unsigned int offset, unsigned int data)
{
	/*The CRP address register bit 16 indicates that we want to do a write */
	REG_WRITE (PCI_CSR_BASE, PCI_CRP_AD_CBE_OFFSET,
		   PCI_CRP_WRITE | offset);
	REG_WRITE (PCI_CSR_BASE, PCI_CRP_WDATA_OFFSET, data);
}

/*struct pci_controller *hose*/
void pci_ixp_init (struct pci_controller *hose)
{
	unsigned int regval;

	hose->first_busno = 0;
	hose->last_busno = 0x00;

	/* System memory space */
	pci_set_region (hose->regions + 0,
			PCI_MEMORY_BUS,
			PCI_MEMORY_PHY, PCI_MEMORY_SIZE, PCI_REGION_MEMORY);

	/* PCI memory space */
	pci_set_region (hose->regions + 1,
			PCI_MEM_BUS,
			PCI_MEM_PHY, PCI_MEM_SIZE, PCI_REGION_MEM);
	/* PCI I/O space */
	pci_set_region (hose->regions + 2,
			PCI_IO_BUS, PCI_IO_PHY, PCI_IO_SIZE, PCI_REGION_IO);

	hose->region_count = 3;

	pci_register_hose (hose);

/*
 ==========================================================
 		Init IXP PCI
 ==========================================================
*/
	REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
	regval |= 1 << 2;
	REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);

	configure_pins ();

	READ_GPIO_REG (IXP425_GPIO_GPOUTR, regval);
	WRITE_GPIO_REG (IXP425_GPIO_GPOUTR, regval & (~(1 << 13)));
	udelay (533);
	sys_pci_gpio_clock_config ();
	REG_WRITE (PCI_CSR_BASE, PCI_INTEN_OFFSET, 0);
	udelay (100);
	READ_GPIO_REG (IXP425_GPIO_GPOUTR, regval);
	WRITE_GPIO_REG (IXP425_GPIO_GPOUTR, regval | (1 << 13));
	udelay (533);
	crp_write (PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_0_DEFAULT);
	crp_write (PCI_CFG_BASE_ADDRESS_1, IXP425_PCI_BAR_1_DEFAULT);
	crp_write (PCI_CFG_BASE_ADDRESS_2, IXP425_PCI_BAR_2_DEFAULT);
	crp_write (PCI_CFG_BASE_ADDRESS_3, IXP425_PCI_BAR_3_DEFAULT);
	crp_write (PCI_CFG_BASE_ADDRESS_4, IXP425_PCI_BAR_4_DEFAULT);
	crp_write (PCI_CFG_BASE_ADDRESS_5, IXP425_PCI_BAR_5_DEFAULT);
	/*Setup PCI-AHB and AHB-PCI address mappings */
	REG_WRITE (PCI_CSR_BASE, PCI_AHBMEMBASE_OFFSET,
		   IXP425_PCI_AHBMEMBASE_DEFAULT);

	REG_WRITE (PCI_CSR_BASE, PCI_AHBIOBASE_OFFSET,
		   IXP425_PCI_AHBIOBASE_DEFAULT);

	REG_WRITE (PCI_CSR_BASE, PCI_PCIMEMBASE_OFFSET,
		   IXP425_PCI_PCIMEMBASE_DEFAULT);

	crp_write (PCI_CFG_SUB_VENDOR_ID, IXP425_PCI_SUB_VENDOR_SYSTEM);

	REG_READ (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
	regval |= PCI_CSR_IC | PCI_CSR_ABE | PCI_CSR_PDS;
	REG_WRITE (PCI_CSR_BASE, PCI_CSR_OFFSET, regval);
	crp_write (PCI_CFG_COMMAND, PCI_CFG_CMD_MAE | PCI_CFG_CMD_BME);
	udelay (1000);

	pci_write_config_word (0, PCI_CFG_COMMAND, INITIAL_PCI_CMD);
	REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
		   | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
#ifdef CONFIG_PCI_SCAN_SHOW
	printf ("Device  bus  dev  func  deviceID  vendorID \n");
#endif
	pci_bus_scan ();
}

void configure_pins (void)
{
	unsigned int regval;

	/* Disable clock on GPIO PIN 14 */
	READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
	WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval & (~(1 << 8)));
	READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);

	READ_GPIO_REG (IXP425_GPIO_GPOER, regval);
	WRITE_GPIO_REG (IXP425_GPIO_GPOER,
			(((~(3 << 13)) & regval) | (0xf << 8)));
	READ_GPIO_REG (IXP425_GPIO_GPOER, regval);

	READ_GPIO_REG (IXP425_GPIO_GPIT2R, regval);
	WRITE_GPIO_REG (IXP425_GPIO_GPIT2R,
			(regval &
			 ((0x1 << 9) | (0x1 << 6) | (0x1 << 3) | 0x1)));
	READ_GPIO_REG (IXP425_GPIO_GPIT2R, regval);

	READ_GPIO_REG (IXP425_GPIO_GPISR, regval);
	WRITE_GPIO_REG (IXP425_GPIO_GPISR, (regval | (0xf << 8)));
	READ_GPIO_REG (IXP425_GPIO_GPISR, regval);
}

void sys_pci_gpio_clock_config (void)
{
	unsigned int regval;

	READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
	regval |= 0x1 << 4;
	WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
	READ_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
	regval |= 0x1 << 8;
	WRITE_GPIO_REG (IXP425_GPIO_GPCLKR, regval);
}

void pci_bus_scan (void)
{
	unsigned int bus = 0, dev, func = 0;
	unsigned short data16;
	unsigned int data32;
	unsigned char intPin;

	/* Assign first device to ourselves */
	devices[0].bus = 0;
	devices[0].device = 0;
	devices[0].func = 0;

	crp_read (PCI_CFG_VENDOR_ID, &data32);

	devices[0].vendor_id = data32 & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK;
	devices[0].device_id = data32 >> 16;
	devices[0].error = FALSE;
	devices[0].bar[NO_BAR].size = 0;	/*dummy - required */

	nDevices = 1;

	nMBars = 0;
	nIOBars = 0;

	for (dev = 0; dev < IXP425_PCI_MAX_DEV; dev++) {

		/*Check whether a device is present */
		if (pci_device_exists (dev) != TRUE) {

			/*Clear error bits in ISR, write 1 to clear */
			REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
				   | PCI_ISR_PFE | PCI_ISR_PPE |
				   PCI_ISR_AHBE);
			continue;
		}

		/*A device is present, add an entry to the array */
		devices[nDevices].bus = bus;
		devices[nDevices].device = dev;
		devices[nDevices].func = func;

		pci_read_config_word (dev, PCI_CFG_VENDOR_ID, &data16);

		devices[nDevices].vendor_id = data16;

		pci_read_config_word (dev, PCI_CFG_DEVICE_ID, &data16);
		devices[nDevices].device_id = data16;

		/*The device is functioning correctly, set error to FALSE */
		devices[nDevices].error = FALSE;

		/*Figure out what BARs are on this device */
		sys_pci_bar_info_get (nDevices, bus, dev, func);
		/*Figure out what INTX# line the card uses */
		pci_read_config_byte (dev, PCI_CFG_DEV_INT_PIN, &intPin);

		/*assign the appropriate irq line */
		if (intPin > PCI_IRQ_LINES) {
			devices[nDevices].error = TRUE;
		} else if (intPin != 0) {
			/*This device uses an interrupt line */
			/*devices[nDevices].irq = ixp425PciIntTranslate[dev][intPin-1]; */
			devices[nDevices].irq = intPin;
		}
#ifdef CONFIG_PCI_SCAN_SHOW
		printf ("%06d    %03d %03d %04d  %08d      %08x\n", nDevices,
			devices[nDevices].vendor_id);
#endif
		nDevices++;

	}

	calc_bars (memBars, nMBars, IXP425_PCI_BAR_MEM_BASE);
	sys_pci_device_bars_write ();

	REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PSE
		   | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE);
}

void sys_pci_bar_info_get (unsigned int devnum,
			   unsigned int bus,
			   unsigned int dev, unsigned int func)
{
	unsigned int data32;
	unsigned int tmp;
	unsigned int size;

	pci_write_config_dword (devnum,
				PCI_CFG_BASE_ADDRESS_0, IXP425_PCI_BAR_QUERY);
	pci_read_config_dword (devnum, PCI_CFG_BASE_ADDRESS_0, &data32);

	devices[devnum].bar[0].address = (data32 & 1);

	if (data32 & 1) {
		/* IO space */
		tmp = data32 & ~0x3;
		size = ~(tmp - 1);
		devices[devnum].bar[0].size = size;

		if (nIOBars < IXP425_PCI_MAX_BAR) {
			ioBars[nIOBars++] = &devices[devnum].bar[0];
		}
	} else {
		/* Mem space */
		tmp = data32 & ~IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
		size = ~(tmp - 1);
		devices[devnum].bar[0].size = size;

		if (nMBars < IXP425_PCI_MAX_BAR) {
			memBars[nMBars++] = &devices[devnum].bar[0];
		} else {
			devices[devnum].error = TRUE;
		}

	}

	devices[devnum].bar[1].size = 0;
}

void sortBars (PciBar * Bars[], unsigned int nBars)
{
	unsigned int i, j;
	PciBar *tmp;

	if (nBars == 0) {
		return;
	}

	/* Sort biggest to smallest */
	for (i = 0; i < nBars - 1; i++) {
		for (j = i + 1; j < nBars; j++) {
			if (Bars[j]->size > Bars[i]->size) {
				/* swap them */
				tmp = Bars[i];
				Bars[i] = Bars[j];
				Bars[j] = tmp;
			}
		}
	}
}

void calc_bars (PciBar * Bars[], unsigned int nBars, unsigned int startAddr)
{
	unsigned int i;

	if (nBars == 0) {
		return;
	}

	for (i = 0; i < nBars; i++) {
		Bars[i]->address |= startAddr;
		startAddr += Bars[i]->size;
	}
}

void sys_pci_device_bars_write (void)
{
	unsigned int i;
	int addr;

	for (i = 1; i < nDevices; i++) {
		if (devices[i].error) {
			continue;
		}

		pci_write_config_dword (devices[i].device,
					PCI_CFG_BASE_ADDRESS_0,
					devices[i].bar[0].address);
		addr = BIT (31 - devices[i].device) |
			(0 << PCI_NP_AD_FUNCSL) |
			(PCI_CFG_BASE_ADDRESS_0 & ~3);
		pci_write_config_dword (devices[i].device,
					PCI_CFG_DEV_INT_LINE, devices[i].irq);

		pci_write_config_word (devices[i].device,
				       PCI_CFG_COMMAND, INITIAL_PCI_CMD);

	}
}


int pci_device_exists (unsigned int deviceNo)
{
	unsigned int vendorId;
	unsigned int regval;

	pci_read_config_dword (deviceNo, PCI_CFG_VENDOR_ID, &vendorId);

	/* There are two ways to find out an empty device.
	 *   1. check Master Abort bit after the access.
	 *   2. check whether the vendor id read back is 0x0.
	 */
	REG_READ (PCI_CSR_BASE, PCI_ISR_OFFSET, regval);
	if ((vendorId != 0x0) && ((regval & PCI_ISR_PFE) == 0)) {
		return TRUE;
	}
	/*no device present, make sure that the master abort bit is reset */

	REG_WRITE (PCI_CSR_BASE, PCI_ISR_OFFSET, PCI_ISR_PFE);
	return FALSE;
}

pci_dev_t pci_find_devices (struct pci_device_id * ids, int devNo)
{
	unsigned int i;
	unsigned int devdidvid;
	unsigned int didvid;
	unsigned int vendorId, deviceId;

	vendorId = ids->vendor;
	deviceId = ids->device;
	didvid = ((deviceId << 16) & IXP425_PCI_TOP_WORD_OF_LONG_MASK) |
		(vendorId & IXP425_PCI_BOTTOM_WORD_OF_LONG_MASK);

	for (i = devNo + 1; i < nDevices; i++) {

		pci_read_config_dword (devices[i].device, PCI_CFG_VENDOR_ID,
				       &devdidvid);

		if (devdidvid == didvid) {
			return devices[i].device;
		}
	}
	return -1;
}
#endif	/* CONFIG_PCI */
