/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2008 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.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <arch/io.h>
#include <delay.h>
#include "sb600.h"

#define HDA_ICII_REG 0x68
#define   HDA_ICII_BUSY (1 << 0)
#define   HDA_ICII_VALID  (1 << 1)

static int set_bits(u32 port, u32 mask, u32 val)
{
	u32 dword;
	int count;

	/* Write (val & ~mask) to port */
	val &= mask;
	dword = read32(port);
	dword &= ~mask;
	dword |= val;
	write32(port, dword);

	/* Wait for readback of register to
	 * match what was just written to it
	 */
	count = 50;
	do {
		/* Wait 1ms based on BKDG wait time */
		mdelay(1);
		dword = read32(port);
		dword &= mask;
	} while ((dword != val) && --count);

	/* Timeout occurred */
	if (!count)
		return -1;
	return 0;
}

static u32 codec_detect(u32 base)
{
	u32 dword;

	/* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
	if (set_bits(base + 0x08, 1, 0) == -1)
		goto no_codec;

	/* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
	if (set_bits(base + 0x08, 1, 1) == -1)
		goto no_codec;

	/* Delay for 1 ms since the BKDG does */
	mdelay(1);

	/* Read in Codec location (BAR + 0xe)[3..0]*/
	dword = read32(base + 0xe);
	dword &= 0x0F;
	if (!dword)
		goto no_codec;

	return dword;

no_codec:
	/* Codec Not found */
	/* Put HDA back in reset (BAR + 0x8) [0] */
	set_bits(base + 0x08, 1, 0);
	printk(BIOS_DEBUG, "No codec!\n");
	return 0;
}

static u32 cim_verb_data[] = {
	0x01471c10,
	0x01471d40,
	0x01471e01,
	0x01471f01,
/* 1 */
	0x01571c12,
	0x01571d10,
	0x01571e01,
	0x01571f01,
/* 2 */
	0x01671c11,
	0x01671d60,
	0x01671e01,
	0x01671f01,
/* 3 */
	0x01771c14,
	0x01771d20,
	0x01771e01,
	0x01771f01,
/* 4 */
	0x01871c30,
	0x01871d90,
	0x01871ea1,
	0x01871f01,
/* 5 */
	0x01971cf0,
	0x01971d11,
	0x01971e11,
	0x01971f41,
/* 6 */
	0x01a71c80,
	0x01a71d30,
	0x01a71e81,
	0x01a71f01,
/* 7 */
	0x01b71cf0,
	0x01b71d11,
	0x01b71e11,
	0x01b71f41,
/* 8 */
	0x01c71cf0,
	0x01c71d11,
	0x01c71e11,
	0x01c71f41,
/* 9 */
	0x01d71cf0,
	0x01d71d11,
	0x01d71e11,
	0x01d71f41,
/* 10 */
	0x01e71c50,
	0x01e71d11,
	0x01e71e44,
	0x01e71f01,
/* 11 */
	0x01f71c60,
	0x01f71d61,
	0x01f71ec4,
	0x01f71f01,
};

static u32 find_verb(u32 viddid, u32 ** verb)
{
	device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2));
	struct southbridge_amd_sb600_config *cfg =
	    (struct southbridge_amd_sb600_config *)azalia_dev->chip_info;
	printk(BIOS_DEBUG, "Dev=%s\n", dev_path(azalia_dev));
	printk(BIOS_DEBUG, "Default viddid=%x\n", cfg->hda_viddid);
	printk(BIOS_DEBUG, "Reading viddid=%x\n", viddid);
	if (!cfg)
		return 0;
	if (viddid != cfg->hda_viddid)
		return 0;
	*verb = (u32 *) cim_verb_data;
	return sizeof(cim_verb_data) / sizeof(u32);
}

/**
 *  Wait 50usec for the codec to indicate it is ready
 *  no response would imply that the codec is non-operative
 */
static int wait_for_ready(u32 base)
{
	/* Use a 50 usec timeout - the Linux kernel uses the
	 * same duration */

	int timeout = 50;

	while(timeout--) {
		u32 dword=read32(base +  HDA_ICII_REG);
		if (!(dword & HDA_ICII_BUSY))
			return 0;
		udelay(1);
	}

	return -1;
}

/**
 *  Wait 50usec for the codec to indicate that it accepted
 *  the previous command.  No response would imply that the code
 *  is non-operative
 */
static int wait_for_valid(u32 base)
{
	/* Use a 50 usec timeout - the Linux kernel uses the
	 * same duration */

	int timeout = 50;
	while(timeout--) {
		u32 dword = read32(base + HDA_ICII_REG);
		if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
			HDA_ICII_VALID)
			return 0;
		udelay(1);
	}

	return 1;
}

static void codec_init(u32 base, int addr)
{
	u32 dword;
	u32 *verb;
	u32 verb_size;
	int i;

	/* 1 */
	if (wait_for_ready(base) == -1)
		return;

	dword = (addr << 28) | 0x000f0000;
	write32(base + 0x60, dword);

	if (wait_for_valid(base) == -1)
		return;

	dword = read32(base + 0x64);

	/* 2 */
	printk(BIOS_DEBUG, "codec viddid: %08x\n", dword);
	verb_size = find_verb(dword, &verb);

	if (!verb_size) {
		printk(BIOS_DEBUG, "No verb!\n");
		return;
	}

	printk(BIOS_DEBUG, "verb_size: %d\n", verb_size);
	/* 3 */
	for (i = 0; i < verb_size; i++) {
		if (wait_for_ready(base) == -1)
			return;

		write32(base + 0x60, verb[i]);

		if (wait_for_valid(base) == -1)
			return;
	}
	printk(BIOS_DEBUG, "verb loaded!\n");
}

static void codecs_init(u32 base, u32 codec_mask)
{
	int i;
	for (i = 2; i >= 0; i--) {
		if (codec_mask & (1 << i))
			codec_init(base, i);
	}
}

static void hda_init(struct device *dev)
{
	u8 byte;
	u32 dword;
	u32 base;
	struct resource *res;
	u32 codec_mask;
	device_t sm_dev;

	/* Enable azalia - PM_io 0x59[4], disable ac97 - PM_io 0x59[1..0] */
	pm_iowrite(0x59, 0xB);

	/* Find the SMBus */
	/* FIXME: Need to find out why the call below crashes. */
	/*sm_dev = dev_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_ATI_SB600_SM, 0);*/
	sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));

	/* Set routing pin - SMBus ExtFunc (0xf8/0xfc) */
	pci_write_config32(sm_dev, 0xf8, 0x00);
	pci_write_config8(sm_dev, 0xfc, 0xAA);
	/* Set INTA - SMBus 0x63 [2..0] */
	byte = pci_read_config8(sm_dev, 0x63);
	byte &= ~0x7;
	byte |= 0x0; /* INTA:0x0 - INTH:0x7 */
	pci_write_config8(sm_dev, 0x63, byte);

	/* Program the 2C to 0x437b1002 */
	dword = 0x437b1002;
	pci_write_config32(dev, 0x2c, dword);

	/* Read in BAR */
	/* Is this right? HDA allows for a 64-bit BAR
	 * but this is only setup for a 32-bit one
	 */
	res = find_resource(dev, 0x10);
	if (!res)
		return;

	base = (u32)res->base;
	printk(BIOS_DEBUG, "base = 0x%x\n", base);
	codec_mask = codec_detect(base);

	if (codec_mask) {
		printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
		codecs_init(base, codec_mask);
	}
}

static struct pci_operations lops_pci = {
	.set_subsystem = pci_dev_set_subsystem,
};

static struct device_operations hda_audio_ops = {
	.read_resources = pci_dev_read_resources,
	.set_resources = pci_dev_set_resources,
	.enable_resources = pci_dev_enable_resources,
	/*.enable           = sb600_enable, */
	.init = hda_init,
	.scan_bus = 0,
	.ops_pci = &lops_pci,
};

static const struct pci_driver hdaaudio_driver __pci_driver = {
	.ops = &hda_audio_ops,
	.vendor = PCI_VENDOR_ID_ATI,
	.device = PCI_DEVICE_ID_ATI_SB600_HDA,
};
