/* SPDX-License-Identifier: GPL-2.0-only */

#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/azalia_device.h>
#include <device/mmio.h>
#include <delay.h>
#include <timer.h>
#include <types.h>

int azalia_set_bits(void *port, u32 mask, u32 val)
{
	struct stopwatch sw;
	u32 reg32;

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

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

	/* Timeout occurred */
	if (stopwatch_expired(&sw))
		return -1;
	return 0;
}

int azalia_enter_reset(u8 *base)
{
	/* Set bit 0 to 0 to enter reset state (BAR + 0x8)[0] */
	return azalia_set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, 0);
}

int azalia_exit_reset(u8 *base)
{
	/* Set bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
	return azalia_set_bits(base + HDA_GCTL_REG, HDA_GCTL_CRST, HDA_GCTL_CRST);
}

static u16 codec_detect(u8 *base)
{
	struct stopwatch sw;
	u16 reg16;

	if (azalia_exit_reset(base) < 0)
		goto no_codec;

	if (CONFIG(AZALIA_LOCK_DOWN_R_WO_GCAP)) {
		/* If GCAP is R/WO, lock it down after deasserting controller reset */
		write16(base + HDA_GCAP_REG, read16(base + HDA_GCAP_REG));
	}

	/* clear STATESTS bits (BAR + 0x0e)[14:0] */
	reg16 = read16(base + HDA_STATESTS_REG);
	reg16 |= 0x7fff;
	write16(base + HDA_STATESTS_REG, reg16);

	/* Wait for readback of register to
	 * match what was just written to it
	 */
	stopwatch_init_msecs_expire(&sw, 50);
	do {
		/* Wait 1ms based on BKDG wait time */
		mdelay(1);
		reg16 = read16(base + HDA_STATESTS_REG);
	} while ((reg16 != 0) && !stopwatch_expired(&sw));

	/* Timeout occurred */
	if (stopwatch_expired(&sw))
		goto no_codec;

	if (azalia_enter_reset(base) < 0)
		goto no_codec;

	if (azalia_exit_reset(base) < 0)
		goto no_codec;

	/* Read in Codec location (BAR + 0x0e)[14:0] */
	reg16 = read16(base + HDA_STATESTS_REG);
	reg16 &= 0x7fff;
	if (!reg16)
		goto no_codec;

	return reg16;

no_codec:
	/* Codec Not found */
	azalia_enter_reset(base);
	printk(BIOS_DEBUG, "azalia_audio: no codec!\n");
	return 0;
}

/*
 * Find a specific entry within a verb table
 *
 * @param verb_table:		verb table data
 * @param verb_table_bytes:	verb table size in bytes
 * @param viddid:		vendor/device to search for
 * @param verb:			pointer to entry within table
 *
 * Returns size of the entry within the verb table,
 * Returns 0 if the entry is not found
 *
 * The HDA verb table is composed of dwords. A set of 4 dwords is
 * grouped together to form a "jack" descriptor.
 *   Bits 31:28 - Codec Address
 *   Bits 27:20 - NID
 *   Bits 19:8  - Verb ID
 *   Bits  7:0  - Payload
 *
 * coreboot groups different codec verb tables into a single table
 * and prefixes each with a specific header consisting of 3
 * dword entries:
 *   1 - Codec Vendor/Device ID
 *   2 - Subsystem ID
 *   3 - Number of jacks (groups of 4 dwords) for this codec
 */
u32 azalia_find_verb(const u32 *verb_table, u32 verb_table_bytes, u32 viddid, const u32 **verb)
{
	int idx = 0;

	while (idx < (verb_table_bytes / sizeof(u32))) {
		/* Header contains the number of jacks, aka groups of 4 dwords */
		u32 verb_size = 4 * verb_table[idx + 2];
		if (verb_table[idx] != viddid) {
			idx += verb_size + 3;	// skip verb + header
			continue;
		}
		*verb = &verb_table[idx + 3];
		return verb_size;
	}

	/* Not all codecs need to load another verb */
	return 0;
}

/*
 * 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(u8 *base)
{
	struct stopwatch sw;
	/* Use a 50 usec timeout - the Linux kernel uses the same duration */
	stopwatch_init_usecs_expire(&sw, 50);

	while (!stopwatch_expired(&sw)) {
		u32 reg32 = read32(base + HDA_ICII_REG);
		if (!(reg32 & HDA_ICII_BUSY))
			return 0;
		udelay(1);
	}

	return -1;
}

/*
 * Wait for the codec to indicate that it accepted the previous command.
 * No response would imply that the codec is non-operative.
 */

static int wait_for_valid(u8 *base)
{
	struct stopwatch sw;
	u32 reg32;

	/* Send the verb to the codec */
	reg32 = read32(base + HDA_ICII_REG);
	reg32 |= HDA_ICII_BUSY | HDA_ICII_VALID;
	write32(base + HDA_ICII_REG, reg32);

	/*
	 * The timeout is never reached when the codec is functioning properly.
	 * Using a small timeout value can result in spurious errors with some
	 * codecs, e.g. a codec that is slow to respond but operates correctly.
	 * When a codec is non-operative, the timeout is only reached once per
	 * verb table, thus the impact on booting time is relatively small. So,
	 * use a reasonably long enough timeout to cover all possible cases.
	 */
	stopwatch_init_msecs_expire(&sw, 1);
	while (!stopwatch_expired(&sw)) {
		reg32 = read32(base + HDA_ICII_REG);
		if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) == HDA_ICII_VALID)
			return 0;
		udelay(1);
	}

	return -1;
}

static int azalia_write_verb(u8 *base, u32 verb)
{
	if (wait_for_ready(base) < 0)
		return -1;

	write32(base + HDA_IC_REG, verb);

	return wait_for_valid(base);
}

int azalia_program_verb_table(u8 *base, const u32 *verbs, u32 verb_size)
{
	if (!verbs)
		return 0;

	for (u32 i = 0; i < verb_size; i++) {
		if (azalia_write_verb(base, verbs[i]) < 0)
			return -1;
	}
	return 0;
}

__weak void mainboard_azalia_program_runtime_verbs(u8 *base, u32 viddid)
{
}

static bool codec_is_operative(u8 *base, const int addr)
{
	if (wait_for_ready(base) < 0) {
		printk(BIOS_DEBUG, "azalia_audio: codec #%d not ready\n", addr);
		return false;
	}

	const u32 reg32 = (addr << 28) | 0x000f0000;
	write32(base + HDA_IC_REG, reg32);

	if (wait_for_valid(base) < 0) {
		printk(BIOS_DEBUG, "azalia_audio: codec #%d not valid\n", addr);
		return false;
	}
	return true;
}

void azalia_codec_init(u8 *base, int addr, const u32 *verb_table, u32 verb_table_bytes)
{
	const u32 viddid = read32(base + HDA_IR_REG);
	const u32 *verb;
	u32 verb_size;

	printk(BIOS_DEBUG, "azalia_audio: initializing codec #%d...\n", addr);
	printk(BIOS_DEBUG, "azalia_audio:  - vendor/device id: 0x%08x\n", viddid);

	verb_size = azalia_find_verb(verb_table, verb_table_bytes, viddid, &verb);

	if (verb_size == 0) {
		printk(BIOS_DEBUG, "azalia_audio:  - no verb!\n");
		return;
	}
	printk(BIOS_DEBUG, "azalia_audio:  - verb size: %u\n", verb_size);

	if (azalia_program_verb_table(base, verb, verb_size) < 0)
		printk(BIOS_DEBUG, "azalia_audio:  - verb not loaded\n");
	else
		printk(BIOS_DEBUG, "azalia_audio:  - verb loaded\n");

	mainboard_azalia_program_runtime_verbs(base, viddid);
}

static bool codec_can_init(const u16 codec_mask, u8 *base, const int addr)
{
	return codec_mask & (1 << addr) && codec_is_operative(base, addr);
}

void azalia_codecs_init(u8 *base, u16 codec_mask)
{
	for (int i = AZALIA_MAX_CODECS - 1; i >= 0; i--) {
		if (codec_can_init(codec_mask, base, i))
			azalia_codec_init(base, i, cim_verb_data, cim_verb_data_size);
	}

	azalia_program_verb_table(base, pc_beep_verbs, pc_beep_verbs_size);
}

void azalia_audio_init(struct device *dev)
{
	u8 *base;
	struct resource *res;
	u16 codec_mask;

	res = probe_resource(dev, PCI_BASE_ADDRESS_0);
	if (!res)
		return;

	// NOTE this will break as soon as the azalia_audio gets a bar above 4G.
	// Is there anything we can do about it?
	base = res2mmio(res, 0, 0);
	printk(BIOS_DEBUG, "azalia_audio: base = %p\n", base);
	codec_mask = codec_detect(base);

	if (codec_mask) {
		printk(BIOS_DEBUG, "azalia_audio: codec_mask = 0x%02x\n", codec_mask);
		azalia_codecs_init(base, codec_mask);
	}
}

struct device_operations default_azalia_audio_ops = {
	.read_resources		= pci_dev_read_resources,
	.set_resources		= pci_dev_set_resources,
	.enable_resources	= pci_dev_enable_resources,
	.init			= azalia_audio_init,
	.ops_pci		= &pci_dev_ops_pci,
};
