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

#include <device/mmio.h>
#include <device/pci_ops.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <option.h>
#include <acpi/acpi_sata.h>
#include <types.h>

#include "chip.h"
#include "pch.h"

typedef struct southbridge_intel_bd82x6x_config config_t;

static inline u32 sir_read(struct device *dev, int idx)
{
	pci_write_config32(dev, SATA_SIRI, idx);
	return pci_read_config32(dev, SATA_SIRD);
}

static inline void sir_write(struct device *dev, int idx, u32 value)
{
	pci_write_config32(dev, SATA_SIRI, idx);
	pci_write_config32(dev, SATA_SIRD, value);
}

static void sata_read_resources(struct device *dev)
{
	struct resource *res;

	pci_dev_read_resources(dev);

	/* Assign fixed resources for IDE legacy mode */

	u8 sata_mode = get_uint_option("sata_mode", 0);
	if (sata_mode != 2)
		return;

	res = probe_resource(dev, PCI_BASE_ADDRESS_0);
	if (res) {
		res->base = 0x1f0;
		res->size = 8;
		res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
	}

	res = probe_resource(dev, PCI_BASE_ADDRESS_1);
	if (res) {
		res->base = 0x3f4;
		res->size = 4;
		res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
	}

	res = probe_resource(dev, PCI_BASE_ADDRESS_2);
	if (res) {
		res->base = 0x170;
		res->size = 8;
		res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
	}

	res = probe_resource(dev, PCI_BASE_ADDRESS_3);
	if (res) {
		res->base = 0x374;
		res->size = 4;
		res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
	}
}

static void sata_set_resources(struct device *dev)
{
	/* work around bug in pci_dev_set_resources(), it bails out on FIXED */
	u8 sata_mode = get_uint_option("sata_mode", 0);
	if (sata_mode == 2) {
		unsigned int i;
		for (i = PCI_BASE_ADDRESS_0; i <= PCI_BASE_ADDRESS_3; i += 4) {
			struct resource *const res = probe_resource(dev, i);
			if (res)
				res->flags &= ~IORESOURCE_FIXED;
		}
	}

	pci_dev_set_resources(dev);
}

static void sata_init(struct device *dev)
{
	u32 reg32;
	u16 reg16;
	/* Get the chip configuration */
	config_t *config = dev->chip_info;

	printk(BIOS_DEBUG, "SATA: Initializing...\n");

	if (config == NULL) {
		printk(BIOS_ERR, "SATA: ERROR: Device not in devicetree.cb!\n");
		return;
	}

	/* Default to AHCI */
	u8 sata_mode = get_uint_option("sata_mode", 0);

	/* SATA configuration */

	/* Enable BARs */
	pci_write_config16(dev, PCI_COMMAND,
			   PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO);

	/* AHCI */
	if (sata_mode == 0) {
		u8 *abar;

		printk(BIOS_DEBUG, "SATA: Controller in AHCI mode.\n");

		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE);
		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE);

		/* for AHCI, Port Enable is managed in memory mapped space */
		reg16 = pci_read_config16(dev, 0x92);
		reg16 &= ~0x3f; /* 6 ports SKU + ORM */
		reg16 |= 0x8000 | config->sata_port_map;
		pci_write_config16(dev, 0x92, reg16);

		/* SATA Initialization register */
		pci_write_config32(dev, 0x94, ((config->sata_port_map ^ 0x3f) << 24) | 0x183);

		/* Initialize AHCI memory-mapped space */
		abar = (u8 *)pci_read_config32(dev, PCI_BASE_ADDRESS_5);
		printk(BIOS_DEBUG, "ABAR: %p\n", abar);
		/* CAP (HBA Capabilities) : enable power management */
		reg32 = read32(abar + 0x00);
		reg32 |= 0x0c006000;  // set PSC+SSC+SALP+SSS
		reg32 &= ~0x00020060; // clear SXS+EMS+PMS
		/* Set ISS, if available */
		if (config->sata_interface_speed_support)
		{
			reg32 &= ~0x00f00000;
			reg32 |= (config->sata_interface_speed_support & 0x03)
			  << 20;
		}
		write32(abar + 0x00, reg32);
		/* PI (Ports implemented) */
		write32(abar + 0x0c, config->sata_port_map);
		(void) read32(abar + 0x0c); /* Read back 1 */
		(void) read32(abar + 0x0c); /* Read back 2 */
		/* CAP2 (HBA Capabilities Extended)*/
		reg32 = read32(abar + 0x24);
		reg32 &= ~0x00000002;
		write32(abar + 0x24, reg32);
		/* VSP (Vendor Specific Register */
		reg32 = read32(abar + 0xa0);
		reg32 &= ~0x00000005;
		write32(abar + 0xa0, reg32);
	} else {
	        /* IDE */

		/* Without AHCI BAR no memory decoding */
		pci_and_config16(dev, PCI_COMMAND, ~PCI_COMMAND_MEMORY);

		if (sata_mode == 1) {
			/* Native mode on both primary and secondary. */
			pci_or_config8(dev, 0x09, 0x05);
			printk(BIOS_DEBUG, "SATA: Controller in IDE compat mode.\n");
		} else {
			/* Legacy mode on both primary and secondary. */
			pci_and_config8(dev, 0x09, ~0x05);
			printk(BIOS_DEBUG, "SATA: Controller in IDE legacy mode.\n");
		}

		/* Enable I/O decoding */
		pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE);
		pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE);

		/* Port enable + OOB retry mode */
		pci_update_config16(dev, 0x92, ~0x3f, config->sata_port_map | 0x8000);

		/* SATA Initialization register */
		pci_write_config32(dev, 0x94, ((config->sata_port_map ^ 0x3f) << 24) | 0x183);
	}

	/* Set Gen3 Transmitter settings if needed */
	if (config->sata_port0_gen3_tx)
		pch_iobp_update(SATA_IOBP_SP0G3IR, 0,
				config->sata_port0_gen3_tx);

	if (config->sata_port1_gen3_tx)
		pch_iobp_update(SATA_IOBP_SP1G3IR, 0,
				config->sata_port1_gen3_tx);

	/* Additional Programming Requirements */
	sir_write(dev, 0x04, 0x00001600);
	sir_write(dev, 0x28, 0xa0000033);
	reg32 = sir_read(dev, 0x54);
	reg32 &= 0xff000000;
	reg32 |= 0x5555aa;
	sir_write(dev, 0x54, reg32);
	sir_write(dev, 0x64, 0xcccc8484);
	reg32 = sir_read(dev, 0x68);
	reg32 &= 0xffff0000;
	reg32 |= 0xcccc;
	sir_write(dev, 0x68, reg32);
	reg32 = sir_read(dev, 0x78);
	reg32 &= 0x0000ffff;
	reg32 |= 0x88880000;
	sir_write(dev, 0x78, reg32);
	sir_write(dev, 0x84, 0x001c7000);
	sir_write(dev, 0x88, 0x88338822);
	sir_write(dev, 0xa0, 0x001c7000);
	// a4
	sir_write(dev, 0xc4, 0x0c0c0c0c);
	sir_write(dev, 0xc8, 0x0c0c0c0c);
	sir_write(dev, 0xd4, 0x10000000);

	pch_iobp_update(0xea004001, 0x3fffffff, 0xc0000000);
	pch_iobp_update(0xea00408a, 0xfffffcff, 0x00000100);

	pci_update_config32(dev, 0x98,
		~(1 << 16 | 0x3f << 7 | 3 << 5 | 3 << 3),
		1 << 24 | 1 << 22 | 1 << 20 | 1 << 19 |
		1 << 18 | 1 << 14 | 0x04 << 7 | 1 << 3);
}

static void sata_enable(struct device *dev)
{
	/* Get the chip configuration */
	config_t *config = dev->chip_info;
	u16 map = 0;

	if (!config)
		return;

	u8 sata_mode = get_uint_option("sata_mode", 0);

	/*
	 * Set SATA controller mode early so the resource allocator can
	 * properly assign IO/Memory resources for the controller.
	 */
	if (sata_mode == 0)
		map = 0x0060;

	map |= (config->sata_port_map ^ 0x3f) << 8;

	pci_write_config16(dev, 0x90, map);
}

static const char *sata_acpi_name(const struct device *dev)
{
	return "SATA";
}

static void sata_fill_ssdt(const struct device *dev)
{
	config_t *config = dev->chip_info;
	generate_sata_ssdt_ports("\\_SB_.PCI0.SATA", config->sata_port_map);
}

static struct device_operations sata_ops = {
	.read_resources		= sata_read_resources,
	.set_resources		= sata_set_resources,
	.enable_resources	= pci_dev_enable_resources,
	.acpi_fill_ssdt		= sata_fill_ssdt,
	.init			= sata_init,
	.enable			= sata_enable,
	.ops_pci		= &pci_dev_ops_pci,
	.acpi_name		= sata_acpi_name,
};

static const unsigned short pci_device_ids[] = { 0x1c00, 0x1c01, 0x1c02, 0x1c03,
						 0x1e00, 0x1e01, 0x1e02, 0x1e03,
						 0 };

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