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

#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <device/mmio.h>
#include <device/azalia_device.h>

#include "pch.h"
#include "hda_verb.h"

static void codecs_init(u8 *base, u32 codec_mask)
{
	int i;

	/* Can support up to 4 codecs */
	for (i = 3; i >= 0; i--) {
		if (codec_mask & (1 << i))
			hda_codec_init(base, i,
				       cim_verb_data_size,
				       cim_verb_data);
	}

	if (pc_beep_verbs_size)
		azalia_program_verb_table(base, pc_beep_verbs, pc_beep_verbs_size);
}

static void azalia_pch_init(struct device *dev, u8 *base)
{
	u8 reg8;
	u16 reg16;
	u32 reg32;

	if (RCBA32(0x2030) & (1 << 31)) {
		reg32 = pci_read_config32(dev, 0x120);
		reg32 &= 0xf8ffff01;
		reg32 |= (1 << 25);
		reg32 |= RCBA32(0x2030) & 0xfe;
		pci_write_config32(dev, 0x120, reg32);

		if (!pch_is_lp()) {
			pci_and_config16(dev, 0x78, ~(1 << 11));
		}
	} else
		printk(BIOS_DEBUG, "Azalia: V1CTL disabled.\n");

	reg32 = pci_read_config32(dev, 0x114);
	reg32 &= ~0xfe;
	pci_write_config32(dev, 0x114, reg32);

	// Set VCi enable bit
	if (pci_read_config32(dev, 0x120) & ((1 << 24) | (1 << 25) | (1 << 26))) {
		reg32 = pci_read_config32(dev, 0x120);
		if (pch_is_lp())
			reg32 &= ~(1 << 31);
		else
			reg32 |= (1 << 31);
		pci_write_config32(dev, 0x120, reg32);
	}

	reg8 = pci_read_config8(dev, 0x43);
	if (pch_is_lp())
		reg8 &= ~(1 << 6);
	else
		reg8 |= (1 << 4);
	pci_write_config8(dev, 0x43, reg8);

	if (!pch_is_lp())
		pci_or_config32(dev, 0xc0, 1 << 17);

	/* Additional programming steps */
	reg32 = pci_read_config32(dev, 0xc4);
	if (pch_is_lp())
		reg32 |= (1 << 24);
	else
		reg32 |= (1 << 14);
	pci_write_config32(dev, 0xc4, reg32);

	if (!pch_is_lp())
		pci_and_config32(dev, 0xd0, ~(1 << 31));

	// Docking not supported
	pci_and_config8(dev, 0x4d, (u8)~(1 << 7)); // Docking Status

	if (pch_is_lp()) {
		reg16 = read32(base + 0x0012);
		reg16 |= (1 << 0);
		write32(base + 0x0012, reg16);

		/* disable Auto Voltage Detector */
		pci_or_config8(dev, 0x42, 1 << 2);
	}
}

static void azalia_init(struct device *dev)
{
	u8 *base;
	struct resource *res;
	u32 codec_mask;

	/* Find base address */
	res = probe_resource(dev, PCI_BASE_ADDRESS_0);
	if (!res)
		return;

	base = res2mmio(res, 0, 0);
	printk(BIOS_DEBUG, "Azalia: base = %p\n", base);

	/* Set Bus Master */
	pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER);

	azalia_pch_init(dev, base);

	codec_mask = hda_codec_detect(base);

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

static void azalia_final(struct device *dev)
{
	/* Set HDCFG.BCLD */
	pci_or_config16(dev, 0x40, 1 << 1);
}

static struct device_operations azalia_ops = {
	.read_resources		= pci_dev_read_resources,
	.set_resources		= pci_dev_set_resources,
	.enable_resources	= pci_dev_enable_resources,
	.init			= azalia_init,
	.final			= azalia_final,
	.ops_pci		= &pci_dev_ops_pci,
};

static const unsigned short pci_device_ids[] = {
	PCI_DEVICE_ID_INTEL_LPT_H_AUDIO,
	PCI_DEVICE_ID_INTEL_LPT_LP_AUDIO,
	0
};

static const struct pci_driver pch_azalia __pci_driver = {
	.ops	 = &azalia_ops,
	.vendor	 = PCI_VENDOR_ID_INTEL,
	.devices = pci_device_ids,
};
