/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2012  Alexandru Gagniuc <mr.nuke.me@gmail.com>
 *
 * 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.
 */

#include <device/pci.h>
#include <device/pci_ids.h>
#include <console/console.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <drivers/generic/ioapic/chip.h>

#include "vx900.h"
#include "chip.h"

/**
 * @file vx900/traf_ctrl.c
 *
 * STATUS:
 * The same issues with the IOAPIC pointe in lpc.c also apply here.
 *
 * We need to check if the current PCIE lane configuration mechanism is sane.
 */

/**
 * \brief VX900: Set up the north module IOAPIC (for PCIE and VGA)
 *
 * Enable the IOAPIC in the south module, and properly set it up.
 * \n
 * This is the hardware specific initialization for the IOAPIC, and complements
 * the setup done by the generic IOAPIC driver. In order for the IOAPIC to work
 * properly, it _must_ be declared in devicetree.cb .
 * \n
 * We are assuming this is called before the drivers/generic/ioapic code,
 * which should be the case if devicetree.cb is set up properly.
 */
static void vx900_north_ioapic_setup(device_t dev)
{
	u8 base_val;
	device_t ioapic;
	ioapic_config_t *config;
	/* Find the IOAPIC, and make sure it's set up correctly in devicetree.cb
	 * If it's not, then the generic ioapic driver will not set it up
	 * correctly, and the MP table will not be correctly generated */
	for (ioapic = dev->next; ioapic; ioapic = ioapic->next) {
		if (ioapic->path.type == DEVICE_PATH_IOAPIC)
			break;
	}
	/* You did put an IOAPIC in devicetree.cb, didn't you? */
	if (ioapic == 0) {
		/* We don't have enough info to set up the IOAPIC */
		printk(BIOS_ERR, "ERROR: North module IOAPIC not found. "
		       "Check your devicetree.cb\n");
		return;
	}
	/* Found our IOAPIC, and it should not carry ISA interrupts */
	config = (ioapic_config_t *) ioapic->chip_info;
	if (config->have_isa_interrupts) {
		/* Umh, is this the right IOAPIC ? */
		printk(BIOS_ERR, "ERROR: North module IOAPIC should not carry "
		       "ISA interrupts.\n" "Check your devicetree.cb\n");
		printk(BIOS_ERR, "Will not initialize this IOAPIC.\n");
		return;
	}
	/* The base address of this IOAPIC _must_
	 *     be between 0xfec00000 and 0xfecfff00
	 *     be 256-byte aligned
	 */
	if ((config->base < (void *)0xfec0000 || config->base > (void *)0xfecfff00)
	    || (((uintptr_t)config->base & 0xff) != 0)) {
		printk(BIOS_ERR, "ERROR: North module IOAPIC base should be "
		       "between 0xfec00000 and 0xfecfff00\n"
		       "and must be aligned to a 256-byte boundary, "
		       "but we found it at 0x%p\n", config->base);
		return;
	}

	printk(BIOS_DEBUG, "VX900 TRAF_CTR: Setting up the north module IOAPIC "
	       "at %p\n", config->base);

	/* First register of the IOAPIC base */
	base_val = (((uintptr_t)config->base) >> 8) & 0xff;
	pci_write_config8(dev, 0x41, base_val);
	/* Second register of the base.
	 * Bit[7] also enables the IOAPIC and bit[5] enables MSI cycles */
	base_val = (((uintptr_t)config->base) >> 16) & 0xf;
	pci_mod_config8(dev, 0x40, 0, base_val | (1 << 7) | (1 << 5));
}

/*
 * Configures the PCI-express ports
 *
 * FIXME: triple-quadruple-check this
 */
static void vx900_pex_link_setup(device_t dev)
{
	u8 reg8;
	struct northbridge_via_vx900_config *nb = (void *)dev->chip_info;

	reg8 = pci_read_config8(dev, 0xb0);
	reg8 &= ~((1 << 7) | (1 << 3));

	if (nb->assign_pex_to_dp)
		reg8 |= (1 << 7);

	if (!nb->pcie_port1_2_lane_wide)
		reg8 |= (1 << 3);

	pci_write_config8(dev, 0xb0, reg8);
}

static void vx900_traf_ctr_init(device_t dev)
{
	vx900_north_ioapic_setup(dev);
	vx900_pex_link_setup(dev);
}

static struct device_operations traf_ctrl_ops = {
	.read_resources = pci_dev_read_resources,
	.set_resources = pci_dev_set_resources,
	.enable_resources = pci_dev_enable_resources,
	.init = vx900_traf_ctr_init,
	/* Need this here, or the IOAPIC driver won't be called.
	 * FIXME: Technically not a LPC bus. */
	.scan_bus = scan_lpc_bus,
};

static const struct pci_driver traf_ctrl_driver __pci_driver = {
	.ops = &traf_ctrl_ops,
	.vendor = PCI_VENDOR_ID_VIA,
	.device = PCI_DEVICE_ID_VIA_VX900_TRAF,
};
