/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2013 Google Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <arch/io.h>
#include <baytrail/pci_devs.h>
#include <baytrail/ramstage.h>
#include <baytrail/sata.h>
#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>

#include "chip.h"

typedef struct soc_intel_baytrail_config config_t;

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_init(struct device *dev)
{
	config_t *config = dev->chip_info;
	u32 reg32;
	u16 reg16;
	u8  reg8;

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

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

	if (!config->sata_ahci) {
		/* Set legacy or native decoding mode */
		if (config->ide_legacy_combined) {
			reg8 = pci_read_config8(dev, 0x09);
			reg8 &= ~0x5;
			pci_write_config8(dev, 0x09, reg8);
		} else {
			reg8 = pci_read_config8(dev, 0x09);
			reg8 |= 0x5;
			pci_write_config8(dev, 0x09, reg8);
		}

		/* Set capabilities pointer */
		pci_write_config8(dev, 0x34, 0x70);
		reg16 = pci_read_config16(dev, 0x70);
		reg16 &= ~0xFF00;
		pci_write_config16(dev, 0x70, reg16);
	}

	/* Primary timing - decode enable */
	reg16 = pci_read_config16(dev, 0x40);
	reg16 |= 1 << 15;
	pci_write_config16(dev, 0x40, reg16);

	/* Secondary timing - decode enable */
	reg16 = pci_read_config16(dev, 0x42);
	reg16 |= 1 << 15;
	pci_write_config16(dev, 0x42, reg16);

	/* Port mapping enables */
	reg16 = pci_read_config16(dev, 0x90);
	reg16 |= (config->sata_port_map ^ 0x3) << 8;
	pci_write_config16(dev, 0x90, reg16);

	/* Port control enables */
	reg16 = pci_read_config16(dev, 0x92);
	reg16 &= ~0x003f;
	reg16 |= config->sata_port_map;
	pci_write_config16(dev, 0x92, reg16);

	if (config->sata_ahci) {
		u32 abar = pci_read_config32(dev, PCI_BASE_ADDRESS_5);

		/* Enable CR memory space decoding */
		reg16 = pci_read_config16(dev, 0x04);
		reg16 |= 0x2;
		pci_write_config16(dev, 0x04, reg16);

		/* Set capibility register */
		reg32 = read32(abar + 0x00);
		reg32 |= 0x0c046000;  // set PSC+SSC+SALP+SSS+SAM
		reg32 &= ~0x00f20060; // clear SXS+EMS+PMS+gen bits
		reg32 |= (0x3 << 20); // Gen3 SATA
		write32(abar + 0x00, reg32);

		/* Ports enabled */
		reg32 = read32(abar + 0x0c);
		reg32 &= (u32)(~0x3f);
		reg32 |= config->sata_port_map;
		write32(abar + 0xc, reg32);
		/* Two extra reads to latch */
		read32(abar + 0x0c);
		read32(abar + 0x0c);

		/* Set cap2 - Support devslp */
		reg32 = (1 << 5) | (1 << 4) | (1 << 3);
		write32(abar + 0x24, reg32);

		/* Set PxCMD registers */
		reg32 = read32(abar + 0x118);
		reg32 &= ~((1 << 27) | (1 << 26) | (1 << 22) | (1 << 21) |
			(1 << 19) | (1 << 18) | (1 << 1));
		reg32 |= 2;
		write32(abar + 0x118, reg32);

		reg32 = read32(abar + 0x198);
		reg32 &= ~((1 << 27) | (1 << 26) | (1 << 22) | (1 << 21) |
			(1 << 19) | (1 << 18) | (1 << 1));
		reg32 |= 2;
		write32(abar + 0x198, reg32);

		/* Clear reset features */
		write32(abar + 0xc8, 0);

		/* Enable interrupts */
		reg8 = read8(abar + 0x04);
		reg8 |= 0x02;
		write8(abar + 0x04, reg8);

	} else {
		/* TODO(shawnn): Configure IDE SATA speed regs */
	}

	/* 1.4 us delay after configuring port / enable bits */
	udelay(2);

	/* Enable clock for ports */
	reg32 = pci_read_config32(dev, 0x94);
	reg32 |= 0x3f << 24;
	pci_write_config32(dev, 0x94, reg32);
	reg32 &= (config->sata_port_map ^ 0x3) << 24;
	pci_write_config32(dev, 0x94, reg32);

	/* Lock SataGc register */
	reg32 = (0x1 << 31) | (0x7 << 12);
	pci_write_config32(dev, 0x98, reg32);
}

static void sata_enable(device_t dev)
{
	config_t *config = dev->chip_info;
	u8  reg8;
	u16 reg16;
	u32 reg32;

	southcluster_enable_dev(dev);
	if (!config)
		return;

	/* Port mapping -- mask off SPD + SMS + SC bits, then re-set */
	reg16 = pci_read_config16(dev, 0x90);
	reg16 &= ~0x03e0;
	reg16 |= (config->sata_port_map ^ 0x3) << 8;
	if(config->sata_ahci)
		reg16 |= 0x60;
	pci_write_config16(dev, 0x90, reg16);

	/* Set reg 0x94 before starting configuration */
	reg32 = pci_read_config32(dev, 0x94);
	reg32 &= (u32)(~0x1ff);
	reg32 |= 0x183;
	pci_write_config32(dev, 0x94, reg32);

	/* Set ORM bit */
	reg16 = pci_read_config16(dev, 0x92);
	reg16 |= (1 << 15);
	pci_write_config16(dev, 0x92, reg16);

	/* R_PCH_SATA_TM2 - Undocumented in EDS, set according to ref. code */
	reg32 = pci_read_config32(dev, 0x98);
	reg32 &= (u32)~(0x1f80 | (1 << 6) | (1 << 5));
	reg32 |= (1 << 29) | (1 << 25) | (1 << 23) | (1 << 22) |
		 (1 << 20) | (1 << 19) | (1 << 18) | (1 << 9) | (1 << 5);
	pci_write_config32(dev, 0x98, reg32);

	/* CMD reg - set bus master enable (BME) */
	reg8 = pci_read_config8(dev, 0x04);
	reg8 |= (1 << 2);
	pci_write_config8(dev, 0x04, reg8);

	/* "Test mode registers" */
	sir_write(dev, 0x70, 0x00288301);
	sir_write(dev, 0x54, 0x00000300);
	sir_write(dev, 0x58, 0x50000000);
	/* "OOB Detection Margin */
	sir_write(dev, 0x6c, 0x130C0603);
	/* "Gasket Control" */
	sir_write(dev, 0xf4, 0);

	/* PCS - Enable requested SATA ports */
	reg8 = pci_read_config8(dev, 0x92);
	reg8 &= ~0x03;
	reg8 |= config->sata_port_map;
	pci_write_config8(dev, 0x92, reg8);
}

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,
	.scan_bus		= NULL,
	.ops_pci		= &soc_pci_ops,
};

static const unsigned short pci_device_ids[] = {
	IDE1_DEVID, IDE2_DEVID,			/* IDE */
	AHCI1_DEVID, AHCI2_DEVID,		/* AHCI */
	0,
};

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