// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2016 Google, Inc
 *
 * From coreboot src/soc/intel/broadwell/sata.c
 */

#include <common.h>
#include <dm.h>
#include <log.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/intel_regs.h>
#include <asm/lpc_common.h>
#include <asm/pch_common.h>
#include <asm/pch_common.h>
#include <asm/arch/pch.h>
#include <linux/delay.h>

struct sata_plat {
	int port_map;
	uint port0_gen3_tx;
	uint port1_gen3_tx;
	uint port0_gen3_dtle;
	uint port1_gen3_dtle;

	/*
	 * SATA DEVSLP Mux
	 * 0 = port 0 DEVSLP on DEVSLP0/GPIO33
	 * 1 = port 3 DEVSLP on DEVSLP0/GPIO33
	 */
	int devslp_mux;

	/*
	 * DEVSLP Disable
	 * 0: DEVSLP is enabled
	 * 1: DEVSLP is disabled
	 */
	int devslp_disable;
};

static void broadwell_sata_init(struct udevice *dev)
{
	struct sata_plat *plat = dev_get_plat(dev);
	u32 reg32;
	u8 *abar;
	u16 reg16;
	int port;

	debug("SATA: Initializing controller in AHCI mode.\n");

	/* Set timings */
	dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE);
	dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE);

	/* for AHCI, Port Enable is managed in memory mapped space */
	dm_pci_read_config16(dev, 0x92, &reg16);
	reg16 &= ~0xf;
	reg16 |= 0x8000 | plat->port_map;
	dm_pci_write_config16(dev, 0x92, reg16);
	udelay(2);

	/* Setup register 98h */
	dm_pci_read_config32(dev, 0x98, &reg32);
	reg32 &= ~((1 << 31) | (1 << 30));
	reg32 |= 1 << 23;
	reg32 |= 1 << 24; /* Enable MPHY Dynamic Power Gating */
	dm_pci_write_config32(dev, 0x98, reg32);

	/* Setup register 9Ch */
	reg16 = 0;           /* Disable alternate ID */
	reg16 = 1 << 5;      /* BWG step 12 */
	dm_pci_write_config16(dev, 0x9c, reg16);

	/* SATA Initialization register */
	reg32 = 0x183;
	reg32 |= (plat->port_map ^ 0xf) << 24;
	reg32 |= (plat->devslp_mux & 1) << 15;
	dm_pci_write_config32(dev, 0x94, reg32);

	/* Initialize AHCI memory-mapped space */
	dm_pci_read_config32(dev, PCI_BASE_ADDRESS_5, &reg32);
	abar = (u8 *)reg32;
	debug("ABAR: %p\n", abar);

	/* CAP (HBA Capabilities) : enable power management */
	clrsetbits_le32(abar + 0x00, 0x00020060 /* SXS+EMS+PMS */,
			0x0c006000 /* PSC+SSC+SALP+SSS */ |
			1 << 18); /* SAM: SATA AHCI MODE ONLY */

	/* PI (Ports implemented) */
	writel(plat->port_map, abar + 0x0c);
	(void) readl(abar + 0x0c); /* Read back 1 */
	(void) readl(abar + 0x0c); /* Read back 2 */

	/* CAP2 (HBA Capabilities Extended)*/
	if (plat->devslp_disable) {
		clrbits_le32(abar + 0x24, 1 << 3);
	} else {
		/* Enable DEVSLP */
		setbits_le32(abar + 0x24, 1 << 5 | 1 << 4 | 1 << 3 | 1 << 2);

		for (port = 0; port < 4; port++) {
			if (!(plat->port_map & (1 << port)))
				continue;
			/* DEVSLP DSP */
			setbits_le32(abar + 0x144 + (0x80 * port), 1 << 1);
		}
	}

	/* Static Power Gating for unused ports */
	reg32 = readl(RCB_REG(0x3a84));
	/* Port 3 and 2 disabled */
	if ((plat->port_map & ((1 << 3)|(1 << 2))) == 0)
		reg32 |= (1 << 24) | (1 << 26);
	/* Port 1 and 0 disabled */
	if ((plat->port_map & ((1 << 1)|(1 << 0))) == 0)
		reg32 |= (1 << 20) | (1 << 18);
	writel(reg32, RCB_REG(0x3a84));

	/* Set Gen3 Transmitter settings if needed */
	if (plat->port0_gen3_tx)
		pch_iobp_update(SATA_IOBP_SP0_SECRT88,
				~(SATA_SECRT88_VADJ_MASK <<
				  SATA_SECRT88_VADJ_SHIFT),
				(plat->port0_gen3_tx &
				 SATA_SECRT88_VADJ_MASK)
				<< SATA_SECRT88_VADJ_SHIFT);

	if (plat->port1_gen3_tx)
		pch_iobp_update(SATA_IOBP_SP1_SECRT88,
				~(SATA_SECRT88_VADJ_MASK <<
				  SATA_SECRT88_VADJ_SHIFT),
				(plat->port1_gen3_tx &
				 SATA_SECRT88_VADJ_MASK)
				<< SATA_SECRT88_VADJ_SHIFT);

	/* Set Gen3 DTLE DATA / EDGE registers if needed */
	if (plat->port0_gen3_dtle) {
		pch_iobp_update(SATA_IOBP_SP0DTLE_DATA,
				~(SATA_DTLE_MASK << SATA_DTLE_DATA_SHIFT),
				(plat->port0_gen3_dtle & SATA_DTLE_MASK)
				<< SATA_DTLE_DATA_SHIFT);

		pch_iobp_update(SATA_IOBP_SP0DTLE_EDGE,
				~(SATA_DTLE_MASK << SATA_DTLE_EDGE_SHIFT),
				(plat->port0_gen3_dtle & SATA_DTLE_MASK)
				<< SATA_DTLE_EDGE_SHIFT);
	}

	if (plat->port1_gen3_dtle) {
		pch_iobp_update(SATA_IOBP_SP1DTLE_DATA,
				~(SATA_DTLE_MASK << SATA_DTLE_DATA_SHIFT),
				(plat->port1_gen3_dtle & SATA_DTLE_MASK)
				<< SATA_DTLE_DATA_SHIFT);

		pch_iobp_update(SATA_IOBP_SP1DTLE_EDGE,
				~(SATA_DTLE_MASK << SATA_DTLE_EDGE_SHIFT),
				(plat->port1_gen3_dtle & SATA_DTLE_MASK)
				<< SATA_DTLE_EDGE_SHIFT);
	}

	/*
	 * Additional Programming Requirements for Power Optimizer
	 */

	/* Step 1 */
	pch_common_sir_write(dev, 0x64, 0x883c9003);

	/* Step 2: SIR 68h[15:0] = 880Ah */
	reg32 = pch_common_sir_read(dev, 0x68);
	reg32 &= 0xffff0000;
	reg32 |= 0x880a;
	pch_common_sir_write(dev, 0x68, reg32);

	/* Step 3: SIR 60h[3] = 1 */
	reg32 = pch_common_sir_read(dev, 0x60);
	reg32 |= (1 << 3);
	pch_common_sir_write(dev, 0x60, reg32);

	/* Step 4: SIR 60h[0] = 1 */
	reg32 = pch_common_sir_read(dev, 0x60);
	reg32 |= (1 << 0);
	pch_common_sir_write(dev, 0x60, reg32);

	/* Step 5: SIR 60h[1] = 1 */
	reg32 = pch_common_sir_read(dev, 0x60);
	reg32 |= (1 << 1);
	pch_common_sir_write(dev, 0x60, reg32);

	/* Clock Gating */
	pch_common_sir_write(dev, 0x70, 0x3f00bf1f);
	pch_common_sir_write(dev, 0x54, 0xcf000f0f);
	pch_common_sir_write(dev, 0x58, 0x00190000);
	clrsetbits_le32(RCB_REG(0x333c), 0x00300000, 0x00c00000);

	dm_pci_read_config32(dev, 0x300, &reg32);
	reg32 |= 1 << 17 | 1 << 16 | 1 << 19;
	reg32 |= 1 << 31 | 1 << 30 | 1 << 29;
	dm_pci_write_config32(dev, 0x300, reg32);

	dm_pci_read_config32(dev, 0x98, &reg32);
	reg32 |= 1 << 29;
	dm_pci_write_config32(dev, 0x98, reg32);

	/* Register Lock */
	dm_pci_read_config32(dev, 0x9c, &reg32);
	reg32 |= 1 << 31;
	dm_pci_write_config32(dev, 0x9c, reg32);
}

static int broadwell_sata_enable(struct udevice *dev)
{
	struct sata_plat *plat = dev_get_plat(dev);
	struct gpio_desc desc;
	u16 map;
	int ret;

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

	map |= (plat->port_map ^ 0x3f) << 8;
	dm_pci_write_config16(dev, 0x90, map);

	ret = gpio_request_by_name(dev, "reset-gpio", 0, &desc, GPIOD_IS_OUT);
	if (ret)
		return ret;

	return 0;
}

static int broadwell_sata_of_to_plat(struct udevice *dev)
{
	struct sata_plat *plat = dev_get_plat(dev);
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);

	plat->port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
	plat->port0_gen3_tx = fdtdec_get_int(blob, node,
					"intel,sata-port0-gen3-tx", 0);

	return 0;
}

static int broadwell_sata_probe(struct udevice *dev)
{
	if (!(gd->flags & GD_FLG_RELOC))
		return broadwell_sata_enable(dev);
	else
		broadwell_sata_init(dev);

	return 0;
}

static const struct udevice_id broadwell_ahci_ids[] = {
	{ .compatible = "intel,wildcatpoint-ahci" },
	{ }
};

U_BOOT_DRIVER(ahci_broadwell_drv) = {
	.name		= "ahci_broadwell",
	.id		= UCLASS_AHCI,
	.of_match	= broadwell_ahci_ids,
	.of_to_plat	= broadwell_sata_of_to_plat,
	.probe		= broadwell_sata_probe,
	.plat_auto	 = sizeof(struct sata_plat),
};
