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

#include <arch/io.h>
#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 <types.h>

#include "chip.h"
#include "i82801jx.h"

typedef struct southbridge_intel_i82801jx_config config_t;

static void sata_enable_ahci_mmap(struct device *const dev, const u8 port_map)
{
	int i;
	u32 reg32;
	struct resource *res;

	/* Initialize AHCI memory-mapped space */
	res = probe_resource(dev, PCI_BASE_ADDRESS_5);
	if (!res)
		return;

	u8 *abar = res2mmio(res, 0, 0);
	printk(BIOS_DEBUG, "ABAR: %p\n", abar);

	/* Set AHCI access mode.
	   No other ABAR registers should be accessed before this. */
	reg32 = read32(abar + 0x04);
	reg32 |= 1 << 31;
	write32(abar + 0x04, reg32);

	/* CAP (HBA Capabilities) : enable power management */
	reg32 = read32(abar + 0x00);
	/* CCCS must be set. */
	reg32 |= 0x0c006080;  /* set CCCS+PSC+SSC+SALP+SSS */
	reg32 &= ~0x00020060; /* clear SXS+EMS+PMS */
	write32(abar + 0x00, reg32);

	/* PI (Ports implemented) */
	write32(abar + 0x0c, port_map);
	/* PCH code reads back twice, do we need it, too? */
	(void) read32(abar + 0x0c); /* Read back 1 */
	(void) read32(abar + 0x0c); /* Read back 2 */

	/* VSP (Vendor Specific Register) */
	reg32 = read32(abar + 0xa0);
	reg32 &= ~0x00000001; /* clear SLPD */
	write32(abar + 0xa0, reg32);

	/* Lock R/WO bits in Port command registers. */
	for (i = 0; i < 6; ++i) {
		u8 *addr = abar + 0x118 + (i * 0x80);
		write32(addr, read32(addr));
	}
}

static void sata_program_indexed(struct device *const dev)
{
	u32 reg32;

	pci_write_config8(dev, D31F2_SIDX, 0x18);
	reg32 = pci_read_config32(dev, D31F2_SDAT);
	reg32 &= ~((7 << 6) | (7 << 3) | (7 << 0));
	reg32 |= (3 << 3) | (3 << 0);
	pci_write_config32(dev, D31F2_SDAT, reg32);

	pci_write_config8(dev, D31F2_SIDX, 0x28);
	pci_write_config32(dev, D31F2_SDAT, 0x00cc2080);

	pci_write_config8(dev, D31F2_SIDX, 0x40);
	pci_write_config8(dev, D31F2_SDAT + 2, 0x22);

	pci_write_config8(dev, D31F2_SIDX, 0x78);
	pci_write_config8(dev, D31F2_SDAT + 2, 0x22);

	pci_write_config8(dev, D31F2_SIDX, 0x84);
	reg32 = pci_read_config32(dev, D31F2_SDAT);
	reg32 &= ~((7 << 3) | (7 << 0));
	reg32 |= (3 << 3) | (3 << 0);
	pci_write_config32(dev, D31F2_SDAT, reg32);

	pci_write_config8(dev, D31F2_SIDX, 0x88);
	reg32 = pci_read_config32(dev, D31F2_SDAT);
	reg32 &= ~((7 << 27) | (7 << 24) | (7 << 11) | (7 << 8));
	reg32 &= ~((7 << 19) | (7 << 16) | (7 <<  3) | (7 << 0));
	reg32 |= (4 << 27) | (4 << 24) | (2 << 11) | (2 << 8);
	reg32 |= (4 << 19) | (4 << 16) | (2 <<  3) | (2 << 0);
	pci_write_config32(dev, D31F2_SDAT, reg32);

	pci_write_config8(dev, D31F2_SIDX, 0x8c);
	reg32 = pci_read_config32(dev, D31F2_SDAT);
	reg32 &= ~((7 << 27) | (7 << 24));
	reg32 &= ~((7 << 19) | (7 << 16) | 0xffff);
	reg32 |= (2 << 27) | (2 << 24);
	reg32 |= (2 << 19) | (2 << 16) | 0x00aa;
	pci_write_config32(dev, D31F2_SDAT, reg32);

	pci_write_config8(dev, D31F2_SIDX, 0x94);
	pci_write_config32(dev, D31F2_SDAT, 0x00000022);

	pci_write_config8(dev, D31F2_SIDX, 0xa0);
	reg32 = pci_read_config32(dev, D31F2_SDAT);
	reg32 &= ~((7 << 3) | (7 << 0));
	reg32 |= (3 << 3) | (3 << 0);
	pci_write_config32(dev, D31F2_SDAT, reg32);

	pci_write_config8(dev, D31F2_SIDX, 0xa8);
	reg32 = pci_read_config32(dev, D31F2_SDAT);
	reg32 &= ~((7 << 19) | (7 << 16) | (7 << 3) | (7 << 0));
	reg32 |= (4 << 19) | (4 << 16) | (2 << 3) | (2 << 0);
	pci_write_config32(dev, D31F2_SDAT, reg32);

	pci_write_config8(dev, D31F2_SIDX, 0xac);
	reg32 = pci_read_config32(dev, D31F2_SDAT);
	reg32 &= ~((7 << 19) | (7 << 16) | 0xffff);
	reg32 |= (2 << 19) | (2 << 16) | 0x000a;
	pci_write_config32(dev, D31F2_SDAT, reg32);
}

static void sata_init(struct device *const dev)
{
	u16 reg16;

	/* Get the chip configuration */
	const config_t *const config = dev->chip_info;

	printk(BIOS_DEBUG, "i82801jx_sata: initializing...\n");

	if (config == NULL) {
		printk(BIOS_ERR, "i82801jx_sata: error: "
				 "device not in devicetree.cb!\n");
		return;
	}

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

	/*
	 * TODO: In contrast to ICH7 and PCH code we don't set
	 * timings, dma and IDE-I/O settings here. Looks like they
	 * became obsolete with the fading of real IDE ports.
	 * Maybe we can safely remove those settings from PCH code and
	 * even ICH7 code if it doesn't use the feature to combine the
	 * IDE and SATA controllers.
	 */

	pci_write_config16(dev, PCI_COMMAND,
			PCI_COMMAND_MASTER |
			PCI_COMMAND_MEMORY | /* read-only in IDE modes */
			PCI_COMMAND_IO);
	if (sata_mode != 0)
		/* No AHCI: clear AHCI base */
		pci_write_config32(dev, PCI_BASE_ADDRESS_5, 0x00000000);

	if (sata_mode == 0) {
		printk(BIOS_DEBUG, "SATA controller in AHCI mode.\n");
	} else {
		printk(BIOS_DEBUG, "SATA controller in native mode.\n");

		/* Enable native mode on both primary and secondary. */
		pci_write_config8(dev, PCI_CLASS_PROG, 0x8f);
	}

	/* Looks like we should only enable decoding here. */
	pci_write_config16(dev, D31F2_IDE_TIM_PRI, (1 << 15));
	pci_write_config16(dev, D31F2_IDE_TIM_SEC, (1 << 15));

	/* Port enable. For AHCI, it's managed in memory mapped space. */
	reg16 = pci_read_config16(dev, 0x92);
	reg16 &= ~0x3f;
	reg16 |= (1 << 15) | ((sata_mode == 0) ? 0x3f : config->sata_port_map);
	pci_write_config16(dev, 0x92, reg16);

	/* SATA clock settings */
	u32 sclkcg = 0;
	if (config->sata_clock_request &&
			!(inb(DEFAULT_GPIOBASE + 0x30) & (1 << (35 - 32))))
		sclkcg |= 1 << 30; /* Enable SATA clock request. */
	/* Disable unused ports. */
	sclkcg |= ((~config->sata_port_map) & 0x3f) << 24;
	/* Must be programmed. */
	sclkcg |= 0x193;
	pci_write_config32(dev, 0x94, sclkcg);

	if (sata_mode == 0)
		sata_enable_ahci_mmap(dev, config->sata_port_map);

	sata_program_indexed(dev);
}

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

	u16 map = 0;

	if (!config)
		return;

	/* Default to AHCI */
	u8 sata_mode = get_int_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 = 0x0040 | 0x0020; /* SATA mode + all ports on D31:F2 */

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

	pci_write_config16(dev, 0x90, map);
}

static struct device_operations sata_ops = {
	.read_resources		= pci_dev_read_resources,
	.set_resources		= pci_dev_set_resources,
	.enable_resources	= pci_dev_enable_resources,
	.init			= sata_init,
	.enable			= sata_enable,
	.ops_pci		= &pci_dev_ops_pci,
};

static const unsigned short pci_device_ids[] = {
	0x3a00,
	0x3a02,
	0x3a05,
	0x3a06,
	0x3a20,
	0x3a22,
	0x3a25,
	0x3a26,
	0,
};

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