/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2003-2004 Linux Networx
 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
 * Copyright (C) 2004 David Hendricks <sc@flagen.com>
 * Copyright (C) 2004 Li-Ta Lo <ollie@lanl.gov>
 * Copyright (C) 2005-2006 Tyan
 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
 * Copyright (C) 2005-2006 Stefan Reinauer <stepan@openbios.org>
 *
 * 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; version 2 of the License.
 *
 * 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.
 */

#include <lib.h>
#include <console/console.h>
#include <device/device.h>
#include <device/path.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/hypertransport.h>

struct ht_link {
	struct device *dev;
	unsigned pos;
	unsigned char ctrl_off, config_off, freq_off, freq_cap_off;
};

static device_t ht_scan_get_devs(device_t *old_devices)
{
	device_t first, last;

	first = *old_devices;
	last = first;

	/*
	 * Extract the chain of devices to (first through last) for the next
	 * hypertransport device.
	 */
	while (last && last->sibling &&
	       (last->sibling->path.type == DEVICE_PATH_PCI) &&
	       (last->sibling->path.pci.devfn > last->path.pci.devfn))
	{
		last = last->sibling;
	}

	if (first) {
		device_t child;

		/* Unlink the chain from the list of old devices. */
		*old_devices = last->sibling;
		last->sibling = 0;

		/* Now add the device to the list of devices on the bus. */
		/* Find the last child of our parent. */
		for (child = first->bus->children; child && child->sibling; )
			child = child->sibling;

		/* Place the chain on the list of children of their parent. */
		if (child)
			child->sibling = first;
		else
			first->bus->children = first;
	}
	return first;
}

static int ht_setup_link(struct ht_link *prev, device_t dev, unsigned pos)
{
	struct ht_link cur[1];
	int linkb_to_host;

	/* Set the hypertransport link width and frequency. */

	/*
	 * See which side of the device our previous write to set the unitid
	 * came from.
	 */
	cur->dev = dev;
	cur->pos = pos;
	linkb_to_host =
	  (pci_read_config16(cur->dev, cur->pos + PCI_CAP_FLAGS) >> 10) & 1;

	if (!linkb_to_host) {
		cur->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL0;
		cur->config_off   = PCI_HT_CAP_SLAVE_WIDTH0;
		cur->freq_off     = PCI_HT_CAP_SLAVE_FREQ0;
		cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
	} else {
		cur->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL1;
		cur->config_off   = PCI_HT_CAP_SLAVE_WIDTH1;
		cur->freq_off     = PCI_HT_CAP_SLAVE_FREQ1;
		cur->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
	}

	/*
	 * Remember the current link as the previous link, but look at the
	 * other offsets.
	 */
	prev->dev = cur->dev;
	prev->pos = cur->pos;
	if (cur->ctrl_off == PCI_HT_CAP_SLAVE_CTRL0) {
		prev->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL1;
		prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH1;
		prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ1;
		prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP1;
	} else {
		prev->ctrl_off     = PCI_HT_CAP_SLAVE_CTRL0;
		prev->config_off   = PCI_HT_CAP_SLAVE_WIDTH0;
		prev->freq_off     = PCI_HT_CAP_SLAVE_FREQ0;
		prev->freq_cap_off = PCI_HT_CAP_SLAVE_FREQ_CAP0;
	}

	return 0;
}

static unsigned ht_lookup_slave_capability(struct device *dev)
{
	unsigned pos;

	pos = 0;
	do {
		pos = pci_find_next_capability(dev, PCI_CAP_ID_HT, pos);
		if (pos) {
			u16 flags;
			flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);
			printk(BIOS_SPEW, "flags: 0x%04x\n", flags);
			if ((flags >> 13) == 0) {
				/* Entry is a slave secondary, success... */
				break;
			}
		}
	} while (pos);

	return pos;
}

static void ht_collapse_early_enumeration(struct bus *bus,
					  unsigned offset_unitid)
{
	unsigned int devfn;
	struct ht_link prev;
	u16 ctrl;

	/* Initialize the hypertransport enumeration state. */
	prev.dev = bus->dev;
	prev.pos = bus->cap;
	prev.ctrl_off     = PCI_HT_CAP_HOST_CTRL;
	prev.config_off   = PCI_HT_CAP_HOST_WIDTH;
	prev.freq_off     = PCI_HT_CAP_HOST_FREQ;
	prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;

	/* Wait until the link initialization is complete. */
	do {
		ctrl = pci_read_config16(prev.dev, prev.pos + prev.ctrl_off);

		/* Is this the end of the hypertransport chain? */
		if (ctrl & (1 << 6))
			return;

		/* Has the link failed? */
		if (ctrl & (1 << 4)) {
			/*
			 * Either the link has failed, or we have a CRC error.
			 * Sometimes this can happen due to link retrain, so
			 * lets knock it down and see if its transient.
			 */
			ctrl |= ((1 << 4) | (1 << 8)); /* Link fail + CRC */
			pci_write_config16(prev.dev, prev.pos + prev.ctrl_off,
					   ctrl);
			ctrl = pci_read_config16(prev.dev,
						 prev.pos + prev.ctrl_off);
			if (ctrl & ((1 << 4) | (1 << 8))) {
				printk(BIOS_ALERT, "Detected error on "
				       "Hypertransport link\n");
				return;
			}
		}
	} while ((ctrl & (1 << 5)) == 0);

	/* Actually, only for one HT device HT chain, and unitid is 0. */
#if !CONFIG_HT_CHAIN_UNITID_BASE
	if (offset_unitid)
		return;
#endif

	/* Check if is already collapsed. */
	if ((!offset_unitid) || (offset_unitid
	    && (!((CONFIG_HT_CHAIN_END_UNITID_BASE == 0)
	    && (CONFIG_HT_CHAIN_END_UNITID_BASE
	    < CONFIG_HT_CHAIN_UNITID_BASE))))) {

		struct device dummy;
		u32 id;

		dummy.bus = bus;
		dummy.path.type = DEVICE_PATH_PCI;
		dummy.path.pci.devfn = PCI_DEVFN(0, 0);

		id = pci_read_config32(&dummy, PCI_VENDOR_ID);
		if (!((id == 0xffffffff) || (id == 0x00000000)
		    || (id == 0x0000ffff) || (id == 0xffff0000))) {
			return;
		}
	}

	/* Spin through the devices and collapse any early HT enumeration. */
	for (devfn = PCI_DEVFN(1, 0); devfn <= 0xff; devfn += 8) {
		struct device dummy;
		u32 id;
		unsigned pos, flags;

		dummy.bus = bus;
		dummy.path.type = DEVICE_PATH_PCI;
		dummy.path.pci.devfn = devfn;

		id = pci_read_config32(&dummy, PCI_VENDOR_ID);
		if ((id == 0xffffffff) || (id == 0x00000000)
		    || (id == 0x0000ffff) || (id == 0xffff0000)) {
			continue;
		}

		dummy.vendor = id & 0xffff;
		dummy.device = (id >> 16) & 0xffff;
		dummy.hdr_type = pci_read_config8(&dummy, PCI_HEADER_TYPE);

		pos = ht_lookup_slave_capability(&dummy);
		if (!pos)
			continue;

		/* Clear the unitid. */
		flags = pci_read_config16(&dummy, pos + PCI_CAP_FLAGS);
		flags &= ~0x1f;
		pci_write_config16(&dummy, pos + PCI_CAP_FLAGS, flags);
		printk(BIOS_SPEW, "Collapsing %s [%04x/%04x]\n",
		       dev_path(&dummy), dummy.vendor, dummy.device);
	}
}

static unsigned int do_hypertransport_scan_chain(struct bus *bus, unsigned min_devfn,
				       unsigned max_devfn,
				       unsigned *ht_unitid_base,
				       unsigned offset_unitid)
{
	/*
	 * Even CONFIG_HT_CHAIN_UNITID_BASE == 0, we still can go through this
	 * function, because of end_of_chain check. Also, we need it to
	 * optimize link.
	 */
	unsigned int next_unitid, last_unitid, min_unitid, max_unitid;
	device_t old_devices, dev, func, last_func = 0;
	struct ht_link prev;
	int ht_dev_num = 0;

	min_unitid = (offset_unitid) ? CONFIG_HT_CHAIN_UNITID_BASE : 1;

#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
        /*
	 * Let's record the device of last HT device, so we can set the unitid
	 * to CONFIG_HT_CHAIN_END_UNITID_BASE.
	 */
	unsigned int real_last_unitid = 0, end_used = 0;
	u8 real_last_pos = 0;
	device_t real_last_dev = NULL;
#endif

	/* Restore the hypertransport chain to it's uninitialized state. */
	ht_collapse_early_enumeration(bus, offset_unitid);

	/* See which static device nodes I have. */
	old_devices = bus->children;
	bus->children = 0;

	/* Initialize the hypertransport enumeration state. */
	prev.dev = bus->dev;
	prev.pos = bus->cap;

	prev.ctrl_off     = PCI_HT_CAP_HOST_CTRL;
	prev.config_off   = PCI_HT_CAP_HOST_WIDTH;
	prev.freq_off     = PCI_HT_CAP_HOST_FREQ;
	prev.freq_cap_off = PCI_HT_CAP_HOST_FREQ_CAP;

	/* If present, assign unitid to a hypertransport chain. */
	last_unitid = min_unitid -1;
	max_unitid = next_unitid = min_unitid;
	do {
		u8 pos;
		u16 flags, ctrl;
		unsigned int count, static_count;

		last_unitid = next_unitid;

		/* Wait until the link initialization is complete. */
		do {
			ctrl = pci_read_config16(prev.dev,
						 prev.pos + prev.ctrl_off);

			/* End of chain? */
			if (ctrl & (1 << 6))
				goto end_of_chain;

			if (ctrl & ((1 << 4) | (1 << 8))) {
				/*
				 * Either the link has failed, or we have a CRC
				 * error. Sometimes this can happen due to link
				 * retrain, so lets knock it down and see if
				 * it's transient.
				 */
				ctrl |= ((1 << 4) | (1 <<8)); // Link fail + CRC
				pci_write_config16(prev.dev,
					prev.pos + prev.ctrl_off, ctrl);
				ctrl = pci_read_config16(prev.dev,
						prev.pos + prev.ctrl_off);
				if (ctrl & ((1 << 4) | (1 << 8))) {
					printk(BIOS_ALERT, "Detected error on "
					       "hypertransport link\n");
					goto end_of_chain;
				}
			}
		} while ((ctrl & (1 << 5)) == 0);


		/* Get and setup the device_structure. */
		dev = ht_scan_get_devs(&old_devices);

		/* See if a device is present and setup the device structure. */
		dev = pci_probe_dev(dev, bus, 0);
		if (!dev || !dev->enabled)
			break;

		/* Find the hypertransport link capability. */
		pos = ht_lookup_slave_capability(dev);
		if (pos == 0) {
			printk(BIOS_ERR, "%s Hypertransport link capability "
			       "not found", dev_path(dev));
			break;
		}

		/* Update the unitid of the current device. */
		flags = pci_read_config16(dev, pos + PCI_CAP_FLAGS);

		/*
		 * If the device has a unitid set and is at devfn 0 we are
		 * done. This can happen with shadow hypertransport devices,
		 * or if we have reached the bottom of a HT device chain.
		 */
		if (flags & 0x1f)
			break;

		flags &= ~0x1f; /* Mask out base Unit ID. */

		count = (flags >> 5) & 0x1f; /* Het unit count. */

#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
		if (offset_unitid) {
			/* max_devfn will be (0x17<<3)|7 or (0x1f<<3)|7. */
			if (next_unitid > (max_devfn >> 3)) {
				if (!end_used) {
			                next_unitid =
					  CONFIG_HT_CHAIN_END_UNITID_BASE;
					end_used = 1;
				} else {
					goto end_of_chain;
				}
			}
		}
#endif

		flags |= next_unitid & 0x1f;
		pci_write_config16(dev, pos + PCI_CAP_FLAGS, flags);

		/* Update the unitid in the device structure. */
		static_count = 1;
		for (func = dev; func; func = func->sibling) {
			func->path.pci.devfn += (next_unitid << 3);
			static_count = (func->path.pci.devfn >> 3)
				        - (dev->path.pci.devfn >> 3) + 1;
			last_func = func;
		}

		/* Compute the number of unitids consumed. */
		printk(BIOS_SPEW, "%s count: %04x static_count: %04x\n",
		       dev_path(dev), count, static_count);
		if (count < static_count)
			count = static_count;

		/* Update the unitid of the next device. */
		ht_unitid_base[ht_dev_num] = next_unitid;
		ht_dev_num++;

#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
		if (offset_unitid) {
			real_last_pos = pos;
			real_last_unitid = next_unitid;
			real_last_dev = dev;
		}
#endif
		next_unitid += count;
		if (next_unitid > max_unitid)
			max_unitid = next_unitid;

		/* Setup the hypertransport link. */
		bus->reset_needed |= ht_setup_link(&prev, dev, pos);

		printk(BIOS_DEBUG, "%s [%04x/%04x] %s next_unitid: %04x\n",
		       dev_path(dev), dev->vendor, dev->device,
		       (dev->enabled? "enabled" : "disabled"), next_unitid);

	} while (last_unitid != next_unitid);

end_of_chain:

#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
	if (offset_unitid && (ht_dev_num > 1)
	    && (real_last_unitid != CONFIG_HT_CHAIN_END_UNITID_BASE)
	    && !end_used) {
		u16 flags;
		flags = pci_read_config16(real_last_dev,
					  real_last_pos + PCI_CAP_FLAGS);
		flags &= ~0x1f;
		flags |= CONFIG_HT_CHAIN_END_UNITID_BASE & 0x1f;
		pci_write_config16(real_last_dev,
				   real_last_pos + PCI_CAP_FLAGS, flags);

		for (func = real_last_dev; func; func = func->sibling) {
			func->path.pci.devfn -= ((real_last_unitid
				- CONFIG_HT_CHAIN_END_UNITID_BASE) << 3);
			last_func = func;
		}

		/* Update last one. */
		ht_unitid_base[ht_dev_num-1] = CONFIG_HT_CHAIN_END_UNITID_BASE;

		printk(BIOS_DEBUG, " unitid: %04x --> %04x\n",
		       real_last_unitid, CONFIG_HT_CHAIN_END_UNITID_BASE);
	}
#endif
	next_unitid = max_unitid;

	if (next_unitid > 0x20)
		next_unitid = 0x20;

	if ((bus->secondary == 0) && (next_unitid > 0x18))
		next_unitid = 0x18; /* Avoid K8 on bus 0. */

	/*
	 * Die if any leftover static devices are are found. There's probably
	 * a problem in devicetree.cb.
	 */
	if (old_devices) {
		device_t left;
		for (left = old_devices; left; left = left->sibling)
			printk(BIOS_DEBUG, "%s\n", dev_path(left));

		printk(BIOS_ERR, "HT: Leftover static devices. "
		       "Check your devicetree.cb\n");

		/*
		 * Put back the leftover static device, and let pci_scan_bus()
		 * disable it.
		 */
		if (last_func && !last_func->sibling)
			last_func->sibling = old_devices;
	}

	return next_unitid;
}

unsigned int hypertransport_scan_chain(struct bus *bus)
{
	int i;
	unsigned int max_devfn;
	u32 ht_unitid_base[4];

	for (i = 0; i < 4; i++)
		ht_unitid_base[i] = 0x20;

	if (bus->secondary == 0)
		max_devfn = (CONFIG_CDB << 3) - 1;
	else
		max_devfn = (0x20 << 3) - 1;

	unsigned int next_unitid = do_hypertransport_scan_chain(bus, 0, max_devfn,
					 ht_unitid_base, offset_unit_id(bus->secondary == 0));

	bus->hcdn_reg = 0;
	for (i = 0; i < 4; i++)
		bus->hcdn_reg |= (ht_unitid_base[i] & 0xff) << (i*8);

	return next_unitid;
}

/**
 * Scan a PCI bridge and the buses behind the bridge.
 *
 * Determine the existence of buses behind the bridge. Set up the bridge
 * according to the result of the scan.
 *
 * This function is the default scan_bus() method for PCI bridge devices.
 *
 * @param bus TODO
 * @param min_devfn TODO
 * @param max_devfn TODO
 */
static void hypertransport_scan_chain_x(struct bus *bus,
	unsigned int min_devfn, unsigned int max_devfn)
{
	unsigned int ht_unitid_base[4];
	unsigned int offset_unitid = 1;

	unsigned int next_unitid = do_hypertransport_scan_chain(bus, min_devfn, max_devfn,
					 ht_unitid_base, offset_unitid);

	/* Now that nothing is overlapping it is safe to scan the children. */
	pci_scan_bus(bus, 0x00, ((next_unitid - 1) << 3) | 7);
}

void ht_scan_bridge(struct device *dev)
{
	do_pci_scan_bridge(dev, hypertransport_scan_chain_x);
}

bool ht_is_non_coherent_link(struct bus *link)
{
	u32 link_type;
	do {
		link_type = pci_read_config32(link->dev, link->cap + 0x18);
	} while (link_type & ConnectionPending);

	if (!(link_type & LinkConnected))
		return false;

	do {
		link_type = pci_read_config32(link->dev, link->cap + 0x18);
	} while (!(link_type & InitComplete));

	return !!(link_type & NonCoherent);
}

/** Default device operations for hypertransport bridges */
static struct pci_operations ht_bus_ops_pci = {
	.set_subsystem = 0,
};

struct device_operations default_ht_ops_bus = {
	.read_resources   = pci_bus_read_resources,
	.set_resources    = pci_dev_set_resources,
	.enable_resources = pci_bus_enable_resources,
	.init             = 0,
	.scan_bus         = ht_scan_bridge,
	.enable           = 0,
	.reset_bus        = pci_bus_reset,
	.ops_pci          = &ht_bus_ops_pci,
};
