/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 *
 * Adapted from usbehcipc.c and usbuhci.c
 */

#define Clegacy 				1
#define CLbiossem 				2
#define CLossem 				3
#define CLcontrol 				4

#include <arch/x86.h>
#include <arch/pci.h>
#include <trap.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <kmalloc.h>
#include <time.h>
#include <mm.h>

static void ehci_disable_leg(struct pci_device *pcidev)
{
	int i, ptr, cap, sem;

	//ptr = (ctlr->capio->capparms >> Ceecpshift) & Ceecpmask;
	uintptr_t bar0 = pci_get_membar(pcidev, 0);
	assert(bar0);
	uintptr_t ehci_hcc_regs = vmap_pmem_nocache(bar0,
						    pcidev->bar[0].mmio_sz);
	uint32_t hccparams = read_mmreg32(ehci_hcc_regs + 0x08);

	ptr = (hccparams >> 8) & ((1 << 8) - 1);

	for (; ptr != 0; ptr = pcidev_read8(pcidev, ptr + 1)) {
		if (ptr < 0x40 || (ptr & ~0xFC))
			break;
		cap = pcidev_read8(pcidev, ptr);
		if (cap != Clegacy)
			continue;
		sem = pcidev_read8(pcidev, ptr + CLbiossem);
		if (sem == 0)
			continue;
		pcidev_write8(pcidev, ptr + CLossem, 1);
		for (i = 0; i < 100; i++) {
			if (pcidev_read8(pcidev, ptr + CLbiossem) == 0)
				break;
			udelay(10);
		}
		if (i == 100)
			printk("PCI EHCI %x:%x:%x: bios timed out\n",
			       pcidev->bus, pcidev->dev, pcidev->func);
		/* bit 29 could be left on, in case we want to give it back */
		pcidev_write32(pcidev, ptr + CLcontrol, 0);	/* no SMIs */
		//ctlr->opio->config = 0;
		//coherence();
		printk("PCI EHCI %x:%x:%x: disabled legacy USB\n",
		       pcidev->bus, pcidev->dev, pcidev->func);
		return;
	}
	printk("PCI EHCI %x:%x:%x: couldn't find legacy capability\n",
	       pcidev->bus, pcidev->dev, pcidev->func);
}

#define XHCI_USBLEGSUP 1

static void xhci_disable_leg(struct pci_device *pcidev)
{
	uintptr_t bar0, xhci_hcc_regs, xecp;
	uint32_t hccparams, val;
	int i;

	bar0 = pci_get_membar(pcidev, 0);
	assert(bar0);
	xhci_hcc_regs = vmap_pmem_nocache(bar0, pcidev->bar[0].mmio_sz);
	hccparams = read_mmreg32(xhci_hcc_regs + 0x10);
	xecp = (hccparams >> 16) & 0xffff;

	/* xecp is the rel offset, in 32 bit words, from the base to the
	 * extended capabilities pointer. */
	for (/* xecp set */; xecp; xecp = (read_mmreg32(xecp) >> 8) & 0xff) {
		xecp = xhci_hcc_regs + (xecp << 2);
		val = read_mmreg32(xecp);

		if ((val & 0xff) != XHCI_USBLEGSUP)
			continue;
		/* bios already does not own it */
		if (!(val & (1 << 16)))
			return;
		/* take ownership.  Note we're allowed to do byte-width writes
		 * here. */
		write_mmreg8(xecp + 3, 1);
		/* book says to wait up to a second, though i regularly see it
		 * time out on my machines. */
		for (i = 0; i < 100000; i++) {
			if (!(read_mmreg32(xecp) & (1 << 16)))
				break;
			udelay(10);
		}
		if (i == 100000) {
			printk("PCI XHCI %x:%x:%x: bios timed out\n",
			       pcidev->bus, pcidev->dev, pcidev->func);
			/* Force the bios's byte clear */
			write_mmreg8(xecp + 2, 0);
		}
		/* Turn off settings in USBLEGCTLSTS.  Not sure if any of this
		 * is necessary. */
		val = read_mmreg32(xecp + 4);
		val &= ~((1 << 0) | (1 << 4) | (0x7 << 13));
		/* These are write-to-clear. */
		val |= 0x7 << 29;
		write_mmreg32(xecp + 4, val);
		printk("PCI XHCI %x:%x:%x: disabled legacy USB\n",
		       pcidev->bus, pcidev->dev, pcidev->func);
		return;
	}
	printk("PCI XHCI %x:%x:%x: couldn't find legacy capability\n",
	       pcidev->bus, pcidev->dev, pcidev->func);
}

static void uhci_disable_leg(struct pci_device *pcidev)
{
	pcidev_write16(pcidev, 0xc0, 0x2000);
	printk("PCI UHCI %x:%x:%x: disabled legacy USB\n",
	       pcidev->bus, pcidev->dev, pcidev->func);
}

void usb_disable_legacy(void)
{
	struct pci_device *i;

	STAILQ_FOREACH(i, &pci_devices, all_dev) {
		if ((i->class == 0x0c) && (i->subclass == 0x03)) {
			switch (i->progif) {
			case 0x00:
				uhci_disable_leg(i);
				break;
			case 0x20:
				ehci_disable_leg(i);
				break;
			case 0x30:
				xhci_disable_leg(i);
				break;
			default:
				/* TODO: ohci */
				printk("PCI USB %x:%x:%x unknown progif 0x%x\n",
				       i->bus, i->dev, i->func, i->progif);
			}
		}
	}
}
