/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2010 Advanced Micro Devices, Inc.
 *
 * 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.
 */

#include <console/console.h>

#include <arch/io.h>

#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include "sb700.h"

static device_t find_sm_dev(device_t dev, u32 devfn)
{
	device_t sm_dev;

	sm_dev = dev_find_slot(dev->bus->secondary, devfn);
	if (!sm_dev)
		return sm_dev;

	if ((sm_dev->vendor != PCI_VENDOR_ID_ATI) ||
	    ((sm_dev->device != PCI_DEVICE_ID_ATI_SB700_SM))) {
		u32 id;
		id = pci_read_config32(sm_dev, PCI_VENDOR_ID);
		if ((id !=
		     (PCI_VENDOR_ID_ATI | (PCI_DEVICE_ID_ATI_SB700_SM << 16))))
		{
			sm_dev = 0;
		}
	}

	return sm_dev;
}

void set_sm_enable_bits(device_t sm_dev, u32 reg_pos, u32 mask, u32 val)
{
	u32 reg_old, reg;
	reg = reg_old = pci_read_config32(sm_dev, reg_pos);
	reg &= ~mask;
	reg |= val;
	if (reg != reg_old) {
		pci_write_config32(sm_dev, reg_pos, reg);
	}
}

static void pmio_write_index(u16 port_base, u8 reg, u8 value)
{
	outb(reg, port_base);
	outb(value, port_base + 1);
}

static u8 pmio_read_index(u16 port_base, u8 reg)
{
	outb(reg, port_base);
	return inb(port_base + 1);
}

void pm_iowrite(u8 reg, u8 value)
{
	pmio_write_index(PM_INDEX, reg, value);
}

u8 pm_ioread(u8 reg)
{
	return pmio_read_index(PM_INDEX, reg);
}

void pm2_iowrite(u8 reg, u8 value)
{
	pmio_write_index(PM2_INDEX, reg, value);
}

u8 pm2_ioread(u8 reg)
{
	return pmio_read_index(PM2_INDEX, reg);
}

static void set_pmio_enable_bits(device_t sm_dev, u32 reg_pos,
				 u32 mask, u32 val)
{
	u8 reg_old, reg;
	reg = reg_old = pm_ioread(reg_pos);
	reg &= ~mask;
	reg |= val;
	if (reg != reg_old) {
		pm_iowrite(reg_pos, reg);
	}
}

void sb7xx_51xx_enable(device_t dev)
{
	device_t sm_dev = 0;
	device_t bus_dev = 0;
	int index = -1;
	u32 deviceid;
	u32 vendorid;

	/* struct southbridge_ati_sb700_config *conf; */
	/* conf = dev->chip_info; */
	int i;

	u32 devfn;

	printk(BIOS_DEBUG, "sb7xx_51xx_enable()\n");

	/*
	 * 0:11.0  SATA	bit 8 of sm_dev 0xac : 1 - enable, default         + 32 * 3
	 * 0:12.0  OHCI0-USB1	bit 0 of sm_dev 0x68
	 * 0:12.1  OHCI1-USB1	bit 1 of sm_dev 0x68
	 * 0:12.2  EHCI-USB1	bit 2 of sm_dev 0x68
	 * 0:13.0  OHCI0-USB2	bit 4 of sm_dev 0x68
	 * 0:13.1  OHCI1-USB2	bit 5 of sm_dev 0x68
	 * 0:13.2  EHCI-USB2	bit 6 of sm_dev 0x68
	 * 0:14.5  OHCI0-USB3	bit 7 of sm_dev 0x68
	 * 0:14.0  SMBUS							0
	 * 0:14.1  IDE							1
	 * 0:14.2  HDA	bit 3 of pm_io 0x59 : 1 - enable, default	    + 32 * 4
	 * 0:14.3  LPC	bit 20 of sm_dev 0x64 : 0 - disable, default  + 32 * 1
	 * 0:14.4  PCI							4
	 */
	if (dev->device == 0x0000) {
		vendorid = pci_read_config32(dev, PCI_VENDOR_ID);
		deviceid = (vendorid >> 16) & 0xffff;
		vendorid &= 0xffff;
	} else {
		vendorid = dev->vendor;
		deviceid = dev->device;
	}

	bus_dev = dev->bus->dev;
	if ((bus_dev->vendor == PCI_VENDOR_ID_ATI) &&
	    (bus_dev->device == PCI_DEVICE_ID_ATI_SB700_PCI)) {
		devfn = (bus_dev->path.pci.devfn) & ~7;
		sm_dev = find_sm_dev(bus_dev, devfn);
		if (!sm_dev)
			return;

		/* something under 00:01.0 */
		switch (dev->path.pci.devfn) {
		case 5 << 3:
			;
		}
		return;
	}

	i = (dev->path.pci.devfn) & ~7;
	i += (3 << 3);
	for (devfn = (0x14 << 3); devfn <= i; devfn += (1 << 3)) {
		sm_dev = find_sm_dev(dev, devfn);
		if (sm_dev)
			break;
	}
	if (!sm_dev)
		return;

	switch (dev->path.pci.devfn - (devfn - (0x14 << 3))) {
	case (0x11 << 3) | 0:
		index = 8;
		set_sm_enable_bits(sm_dev, 0xac, 1 << index,
				   (dev->enabled ? 1 : 0) << index);
		index += 32 * 3;
		break;
	case (0x12 << 3) | 0:
	case (0x12 << 3) | 1:
	case (0x12 << 3) | 2:
		index = dev->path.pci.devfn & 3;
		set_sm_enable_bits(sm_dev, 0x68, 1 << index,
				   (dev->enabled ? 1 : 0) << index);
		index += 32 * 2;
		break;
	case (0x13 << 3) | 0:
	case (0x13 << 3) | 1:
	case (0x13 << 3) | 2:
		index = (dev->path.pci.devfn & 3) + 4;
		set_sm_enable_bits(sm_dev, 0x68, 1 << index,
				   (dev->enabled ? 1 : 0) << index);
		index += 32 * 2;
		break;
	case (0x14 << 3) | 5:
		index = 7;
		set_sm_enable_bits(sm_dev, 0x68, 1 << index,
				   (dev->enabled ? 1 : 0) << index);
		index += 32 * 2;
		break;
	case (0x14 << 3) | 0:
		index = 0;
		break;
	case (0x14 << 3) | 1:
		index = 1;
		break;
	case (0x14 << 3) | 2:
		index = 3;
		set_pmio_enable_bits(sm_dev, 0x59, 1 << index,
				     (dev->enabled ? 1 : 0) << index);
		index += 32 * 4;
		break;
	case (0x14 << 3) | 3:
		index = 20;
		set_sm_enable_bits(sm_dev, 0x64, 1 << index,
				   (dev->enabled ? 1 : 0) << index);
		index += 32 * 1;
		break;
	case (0x14 << 3) | 4:
		index = 4;
		break;
	default:
		printk(BIOS_DEBUG, "unknown dev: %s deviceid=%4x\n", dev_path(dev),
			     deviceid);
	}
}

#if CONFIG_SOUTHBRIDGE_AMD_SUBTYPE_SP5100
struct chip_operations southbridge_amd_sb700_ops = {
	CHIP_NAME("ATI SP5100")
	.enable_dev = sb7xx_51xx_enable,
};
#else
struct chip_operations southbridge_amd_sb700_ops = {
	CHIP_NAME("ATI SB700")
	.enable_dev = sb7xx_51xx_enable,
};
#endif
