/*
 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Andreas Heppel <aheppel@sysgo.de>
 *
 * (C) Copyright 2002, 2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * PCI routines
 */

#include <common.h>

#include <command.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>

#define PCI_HOSE_OP(rw, size, type)					\
int pci_hose_##rw##_config_##size(struct pci_controller *hose,		\
				  pci_dev_t dev,			\
				  int offset, type value)		\
{									\
	return hose->rw##_##size(hose, dev, offset, value);		\
}

PCI_HOSE_OP(read, byte, u8 *)
PCI_HOSE_OP(read, word, u16 *)
PCI_HOSE_OP(read, dword, u32 *)
PCI_HOSE_OP(write, byte, u8)
PCI_HOSE_OP(write, word, u16)
PCI_HOSE_OP(write, dword, u32)

#define PCI_OP(rw, size, type, error_code)				\
int pci_##rw##_config_##size(pci_dev_t dev, int offset, type value)	\
{									\
	struct pci_controller *hose = pci_bus_to_hose(PCI_BUS(dev));	\
									\
	if (!hose)							\
	{								\
		error_code;						\
		return -1;						\
	}								\
									\
	return pci_hose_##rw##_config_##size(hose, dev, offset, value);	\
}

PCI_OP(read, byte, u8 *, *value = 0xff)
PCI_OP(read, word, u16 *, *value = 0xffff)
PCI_OP(read, dword, u32 *, *value = 0xffffffff)
PCI_OP(write, byte, u8, )
PCI_OP(write, word, u16, )
PCI_OP(write, dword, u32, )

#define PCI_READ_VIA_DWORD_OP(size, type, off_mask)			\
int pci_hose_read_config_##size##_via_dword(struct pci_controller *hose,\
					pci_dev_t dev,			\
					int offset, type val)		\
{									\
	u32 val32;							\
									\
	if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0) {	\
		*val = -1;						\
		return -1;						\
	}								\
									\
	*val = (val32 >> ((offset & (int)off_mask) * 8));		\
									\
	return 0;							\
}

#define PCI_WRITE_VIA_DWORD_OP(size, type, off_mask, val_mask)		\
int pci_hose_write_config_##size##_via_dword(struct pci_controller *hose,\
					     pci_dev_t dev,		\
					     int offset, type val)	\
{									\
	u32 val32, mask, ldata, shift;					\
									\
	if (pci_hose_read_config_dword(hose, dev, offset & 0xfc, &val32) < 0)\
		return -1;						\
									\
	shift = ((offset & (int)off_mask) * 8);				\
	ldata = (((unsigned long)val) & val_mask) << shift;		\
	mask = val_mask << shift;					\
	val32 = (val32 & ~mask) | ldata;				\
									\
	if (pci_hose_write_config_dword(hose, dev, offset & 0xfc, val32) < 0)\
		return -1;						\
									\
	return 0;							\
}

PCI_READ_VIA_DWORD_OP(byte, u8 *, 0x03)
PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)

/* Get a virtual address associated with a BAR region */
void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
{
	pci_addr_t pci_bus_addr;
	u32 bar_response;

	/* read BAR address */
	pci_read_config_dword(pdev, bar, &bar_response);
	pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);

	/*
	 * Pass "0" as the length argument to pci_bus_to_virt.  The arg
	 * isn't actualy used on any platform because u-boot assumes a static
	 * linear mapping.  In the future, this could read the BAR size
	 * and pass that as the size if needed.
	 */
	return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
}

/*
 *
 */

static struct pci_controller* hose_head;

void pci_register_hose(struct pci_controller* hose)
{
	struct pci_controller **phose = &hose_head;

	while(*phose)
		phose = &(*phose)->next;

	hose->next = NULL;

	*phose = hose;
}

struct pci_controller *pci_bus_to_hose(int bus)
{
	struct pci_controller *hose;

	for (hose = hose_head; hose; hose = hose->next) {
		if (bus >= hose->first_busno && bus <= hose->last_busno)
			return hose;
	}

	printf("pci_bus_to_hose() failed\n");
	return NULL;
}

struct pci_controller *find_hose_by_cfg_addr(void *cfg_addr)
{
	struct pci_controller *hose;

	for (hose = hose_head; hose; hose = hose->next) {
		if (hose->cfg_addr == cfg_addr)
			return hose;
	}

	return NULL;
}

int pci_last_busno(void)
{
	struct pci_controller *hose = hose_head;

	if (!hose)
		return -1;

	while (hose->next)
		hose = hose->next;

	return hose->last_busno;
}

pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
{
	struct pci_controller * hose;
	u16 vendor, device;
	u8 header_type;
	pci_dev_t bdf;
	int i, bus, found_multi = 0;

	for (hose = hose_head; hose; hose = hose->next) {
#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
		for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
#else
		for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
#endif
			for (bdf = PCI_BDF(bus, 0, 0);
#if defined(CONFIG_ELPPC) || defined(CONFIG_PPMC7XX)
			     bdf < PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
				PCI_MAX_PCI_FUNCTIONS - 1);
#else
			     bdf < PCI_BDF(bus + 1, 0, 0);
#endif
			     bdf += PCI_BDF(0, 0, 1)) {
				if (!PCI_FUNC(bdf)) {
					pci_read_config_byte(bdf,
							     PCI_HEADER_TYPE,
							     &header_type);

					found_multi = header_type & 0x80;
				} else {
					if (!found_multi)
						continue;
				}

				pci_read_config_word(bdf,
						     PCI_VENDOR_ID,
						     &vendor);
				pci_read_config_word(bdf,
						     PCI_DEVICE_ID,
						     &device);

				for (i = 0; ids[i].vendor != 0; i++) {
					if (vendor == ids[i].vendor &&
					    device == ids[i].device) {
						if (index <= 0)
							return bdf;

						index--;
					}
				}
			}
	}

	return -1;
}

pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
{
	static struct pci_device_id ids[2] = {{}, {0, 0}};

	ids[0].vendor = vendor;
	ids[0].device = device;

	return pci_find_devices(ids, index);
}

/*
 *
 */

int __pci_hose_phys_to_bus(struct pci_controller *hose,
				phys_addr_t phys_addr,
				unsigned long flags,
				unsigned long skip_mask,
				pci_addr_t *ba)
{
	struct pci_region *res;
	pci_addr_t bus_addr;
	int i;

	for (i = 0; i < hose->region_count; i++) {
		res = &hose->regions[i];

		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
			continue;

		if (res->flags & skip_mask)
			continue;

		bus_addr = phys_addr - res->phys_start + res->bus_start;

		if (bus_addr >= res->bus_start &&
			bus_addr < res->bus_start + res->size) {
			*ba = bus_addr;
			return 0;
		}
	}

	return 1;
}

pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
				    phys_addr_t phys_addr,
				    unsigned long flags)
{
	pci_addr_t bus_addr = 0;
	int ret;

	if (!hose) {
		puts("pci_hose_phys_to_bus: invalid hose\n");
		return bus_addr;
	}

	/*
	 * if PCI_REGION_MEM is set we do a two pass search with preference
	 * on matches that don't have PCI_REGION_SYS_MEMORY set
	 */
	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
		ret = __pci_hose_phys_to_bus(hose, phys_addr,
				flags, PCI_REGION_SYS_MEMORY, &bus_addr);
		if (!ret)
			return bus_addr;
	}

	ret = __pci_hose_phys_to_bus(hose, phys_addr, flags, 0, &bus_addr);

	if (ret)
		puts("pci_hose_phys_to_bus: invalid physical address\n");

	return bus_addr;
}

int __pci_hose_bus_to_phys(struct pci_controller *hose,
				pci_addr_t bus_addr,
				unsigned long flags,
				unsigned long skip_mask,
				phys_addr_t *pa)
{
	struct pci_region *res;
	int i;

	for (i = 0; i < hose->region_count; i++) {
		res = &hose->regions[i];

		if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
			continue;

		if (res->flags & skip_mask)
			continue;

		if (bus_addr >= res->bus_start &&
			(bus_addr - res->bus_start) < res->size) {
			*pa = (bus_addr - res->bus_start + res->phys_start);
			return 0;
		}
	}

	return 1;
}

phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
				 pci_addr_t bus_addr,
				 unsigned long flags)
{
	phys_addr_t phys_addr = 0;
	int ret;

	if (!hose) {
		puts("pci_hose_bus_to_phys: invalid hose\n");
		return phys_addr;
	}

	/*
	 * if PCI_REGION_MEM is set we do a two pass search with preference
	 * on matches that don't have PCI_REGION_SYS_MEMORY set
	 */
	if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
		ret = __pci_hose_bus_to_phys(hose, bus_addr,
				flags, PCI_REGION_SYS_MEMORY, &phys_addr);
		if (!ret)
			return phys_addr;
	}

	ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);

	if (ret)
		puts("pci_hose_bus_to_phys: invalid physical address\n");

	return phys_addr;
}

/*
 *
 */

int pci_hose_config_device(struct pci_controller *hose,
			   pci_dev_t dev,
			   unsigned long io,
			   pci_addr_t mem,
			   unsigned long command)
{
	u32 bar_response;
	unsigned int old_command;
	pci_addr_t bar_value;
	pci_size_t bar_size;
	unsigned char pin;
	int bar, found_mem64;

	debug("PCI Config: I/O=0x%lx, Memory=0x%llx, Command=0x%lx\n", io,
		(u64)mem, command);

	pci_hose_write_config_dword(hose, dev, PCI_COMMAND, 0);

	for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar += 4) {
		pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
		pci_hose_read_config_dword(hose, dev, bar, &bar_response);

		if (!bar_response)
			continue;

		found_mem64 = 0;

		/* Check the BAR type and set our address mask */
		if (bar_response & PCI_BASE_ADDRESS_SPACE) {
			bar_size = ~(bar_response & PCI_BASE_ADDRESS_IO_MASK) + 1;
			/* round up region base address to a multiple of size */
			io = ((io - 1) | (bar_size - 1)) + 1;
			bar_value = io;
			/* compute new region base address */
			io = io + bar_size;
		} else {
			if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
				PCI_BASE_ADDRESS_MEM_TYPE_64) {
				u32 bar_response_upper;
				u64 bar64;
				pci_hose_write_config_dword(hose, dev, bar + 4,
					0xffffffff);
				pci_hose_read_config_dword(hose, dev, bar + 4,
					&bar_response_upper);

				bar64 = ((u64)bar_response_upper << 32) | bar_response;

				bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
				found_mem64 = 1;
			} else {
				bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
			}

			/* round up region base address to multiple of size */
			mem = ((mem - 1) | (bar_size - 1)) + 1;
			bar_value = mem;
			/* compute new region base address */
			mem = mem + bar_size;
		}

		/* Write it out and update our limit */
		pci_hose_write_config_dword (hose, dev, bar, (u32)bar_value);

		if (found_mem64) {
			bar += 4;
#ifdef CONFIG_SYS_PCI_64BIT
			pci_hose_write_config_dword(hose, dev, bar,
				(u32)(bar_value >> 32));
#else
			pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
#endif
		}
	}

	/* Configure Cache Line Size Register */
	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);

	/* Configure Latency Timer */
	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);

	/* Disable interrupt line, if device says it wants to use interrupts */
	pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &pin);
	if (pin != 0) {
		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE, 0xff);
	}

	pci_hose_read_config_dword(hose, dev, PCI_COMMAND, &old_command);
	pci_hose_write_config_dword(hose, dev, PCI_COMMAND,
				     (old_command & 0xffff0000) | command);

	return 0;
}

/*
 *
 */

struct pci_config_table *pci_find_config(struct pci_controller *hose,
					 unsigned short class,
					 unsigned int vendor,
					 unsigned int device,
					 unsigned int bus,
					 unsigned int dev,
					 unsigned int func)
{
	struct pci_config_table *table;

	for (table = hose->config_table; table && table->vendor; table++) {
		if ((table->vendor == PCI_ANY_ID || table->vendor == vendor) &&
		    (table->device == PCI_ANY_ID || table->device == device) &&
		    (table->class  == PCI_ANY_ID || table->class  == class)  &&
		    (table->bus    == PCI_ANY_ID || table->bus    == bus)    &&
		    (table->dev    == PCI_ANY_ID || table->dev    == dev)    &&
		    (table->func   == PCI_ANY_ID || table->func   == func)) {
			return table;
		}
	}

	return NULL;
}

void pci_cfgfunc_config_device(struct pci_controller *hose,
			       pci_dev_t dev,
			       struct pci_config_table *entry)
{
	pci_hose_config_device(hose, dev, entry->priv[0], entry->priv[1],
		entry->priv[2]);
}

void pci_cfgfunc_do_nothing(struct pci_controller *hose,
			    pci_dev_t dev, struct pci_config_table *entry)
{
}

/*
 * HJF: Changed this to return int. I think this is required
 * to get the correct result when scanning bridges
 */
extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);

#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
const char * pci_class_str(u8 class)
{
	switch (class) {
	case PCI_CLASS_NOT_DEFINED:
		return "Build before PCI Rev2.0";
		break;
	case PCI_BASE_CLASS_STORAGE:
		return "Mass storage controller";
		break;
	case PCI_BASE_CLASS_NETWORK:
		return "Network controller";
		break;
	case PCI_BASE_CLASS_DISPLAY:
		return "Display controller";
		break;
	case PCI_BASE_CLASS_MULTIMEDIA:
		return "Multimedia device";
		break;
	case PCI_BASE_CLASS_MEMORY:
		return "Memory controller";
		break;
	case PCI_BASE_CLASS_BRIDGE:
		return "Bridge device";
		break;
	case PCI_BASE_CLASS_COMMUNICATION:
		return "Simple comm. controller";
		break;
	case PCI_BASE_CLASS_SYSTEM:
		return "Base system peripheral";
		break;
	case PCI_BASE_CLASS_INPUT:
		return "Input device";
		break;
	case PCI_BASE_CLASS_DOCKING:
		return "Docking station";
		break;
	case PCI_BASE_CLASS_PROCESSOR:
		return "Processor";
		break;
	case PCI_BASE_CLASS_SERIAL:
		return "Serial bus controller";
		break;
	case PCI_BASE_CLASS_INTELLIGENT:
		return "Intelligent controller";
		break;
	case PCI_BASE_CLASS_SATELLITE:
		return "Satellite controller";
		break;
	case PCI_BASE_CLASS_CRYPT:
		return "Cryptographic device";
		break;
	case PCI_BASE_CLASS_SIGNAL_PROCESSING:
		return "DSP";
		break;
	case PCI_CLASS_OTHERS:
		return "Does not fit any class";
		break;
	default:
	return  "???";
		break;
	};
}
#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */

int __pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
{
	/*
	 * Check if pci device should be skipped in configuration
	 */
	if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
		/*
		 * Only skip configuration if "pciconfighost" is not set
		 */
		if (getenv("pciconfighost") == NULL)
			return 1;
#else
		return 1;
#endif
	}

	return 0;
}
int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
	__attribute__((weak, alias("__pci_skip_dev")));

#ifdef CONFIG_PCI_SCAN_SHOW
int __pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
{
	if (dev == PCI_BDF(hose->first_busno, 0, 0))
		return 0;

	return 1;
}
int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
	__attribute__((weak, alias("__pci_print_dev")));
#endif /* CONFIG_PCI_SCAN_SHOW */

int pci_hose_scan_bus(struct pci_controller *hose, int bus)
{
	unsigned int sub_bus, found_multi = 0;
	unsigned short vendor, device, class;
	unsigned char header_type;
#ifndef CONFIG_PCI_PNP
	struct pci_config_table *cfg;
#endif
	pci_dev_t dev;
#ifdef CONFIG_PCI_SCAN_SHOW
	static int indent = 0;
#endif

	sub_bus = bus;

	for (dev =  PCI_BDF(bus,0,0);
	     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
				PCI_MAX_PCI_FUNCTIONS - 1);
	     dev += PCI_BDF(0, 0, 1)) {

		if (pci_skip_dev(hose, dev))
			continue;

		if (PCI_FUNC(dev) && !found_multi)
			continue;

		pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);

		pci_hose_read_config_word(hose, dev, PCI_VENDOR_ID, &vendor);

		if (vendor == 0xffff || vendor == 0x0000)
			continue;

		if (!PCI_FUNC(dev))
			found_multi = header_type & 0x80;

		debug("PCI Scan: Found Bus %d, Device %d, Function %d\n",
			PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));

		pci_hose_read_config_word(hose, dev, PCI_DEVICE_ID, &device);
		pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);

#ifdef CONFIG_PCI_FIXUP_DEV
		board_pci_fixup_dev(hose, dev, vendor, device, class);
#endif

#ifdef CONFIG_PCI_SCAN_SHOW
		indent++;

		/* Print leading space, including bus indentation */
		printf("%*c", indent + 1, ' ');

		if (pci_print_dev(hose, dev)) {
			printf("%02x:%02x.%-*x - %04x:%04x - %s\n",
			       PCI_BUS(dev), PCI_DEV(dev), 6 - indent, PCI_FUNC(dev),
			       vendor, device, pci_class_str(class >> 8));
		}
#endif

#ifdef CONFIG_PCI_PNP
		sub_bus = max(pciauto_config_device(hose, dev), sub_bus);
#else
		cfg = pci_find_config(hose, class, vendor, device,
				      PCI_BUS(dev), PCI_DEV(dev), PCI_FUNC(dev));
		if (cfg) {
			cfg->config_device(hose, dev, cfg);
			sub_bus = max(sub_bus, hose->current_busno);
		}
#endif

#ifdef CONFIG_PCI_SCAN_SHOW
		indent--;
#endif

		if (hose->fixup_irq)
			hose->fixup_irq(hose, dev);
	}

	return sub_bus;
}

int pci_hose_scan(struct pci_controller *hose)
{
#if defined(CONFIG_PCI_BOOTDELAY)
	static int pcidelay_done;
	char *s;
	int i;

	if (!pcidelay_done) {
		/* wait "pcidelay" ms (if defined)... */
		s = getenv("pcidelay");
		if (s) {
			int val = simple_strtoul(s, NULL, 10);
			for (i = 0; i < val; i++)
				udelay(1000);
		}
		pcidelay_done = 1;
	}
#endif /* CONFIG_PCI_BOOTDELAY */

	/*
	 * Start scan at current_busno.
	 * PCIe will start scan at first_busno+1.
	 */
	/* For legacy support, ensure current >= first */
	if (hose->first_busno > hose->current_busno)
		hose->current_busno = hose->first_busno;
#ifdef CONFIG_PCI_PNP
	pciauto_config_init(hose);
#endif
	return pci_hose_scan_bus(hose, hose->current_busno);
}

void pci_init(void)
{
	hose_head = NULL;

	/* now call board specific pci_init()... */
	pci_init_board();
}

/* Returns the address of the requested capability structure within the
 * device's PCI configuration space or 0 in case the device does not
 * support it.
 * */
int pci_hose_find_capability(struct pci_controller *hose, pci_dev_t dev,
			     int cap)
{
	int pos;
	u8 hdr_type;

	pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &hdr_type);

	pos = pci_hose_find_cap_start(hose, dev, hdr_type & 0x7F);

	if (pos)
		pos = pci_find_cap(hose, dev, pos, cap);

	return pos;
}

/* Find the header pointer to the Capabilities*/
int pci_hose_find_cap_start(struct pci_controller *hose, pci_dev_t dev,
			    u8 hdr_type)
{
	u16 status;

	pci_hose_read_config_word(hose, dev, PCI_STATUS, &status);

	if (!(status & PCI_STATUS_CAP_LIST))
		return 0;

	switch (hdr_type) {
	case PCI_HEADER_TYPE_NORMAL:
	case PCI_HEADER_TYPE_BRIDGE:
		return PCI_CAPABILITY_LIST;
	case PCI_HEADER_TYPE_CARDBUS:
		return PCI_CB_CAPABILITY_LIST;
	default:
		return 0;
	}
}

int pci_find_cap(struct pci_controller *hose, pci_dev_t dev, int pos, int cap)
{
	int ttl = PCI_FIND_CAP_TTL;
	u8 id;
	u8 next_pos;

	while (ttl--) {
		pci_hose_read_config_byte(hose, dev, pos, &next_pos);
		if (next_pos < CAP_START_POS)
			break;
		next_pos &= ~3;
		pos = (int) next_pos;
		pci_hose_read_config_byte(hose, dev,
					  pos + PCI_CAP_LIST_ID, &id);
		if (id == 0xff)
			break;
		if (id == cap)
			return pos;
		pos += PCI_CAP_LIST_NEXT;
	}
	return 0;
}
