// SPDX-License-Identifier: GPL-2.0-only
/*
 * AMD Seattle AHCI SATA driver
 *
 * Copyright (c) 2015, Advanced Micro Devices
 * Author: Brijesh Singh <brijesh.singh@amd.com>
 *
 * based on the AHCI SATA platform driver by Jeff Garzik and Anton Vorontsov
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/libata.h>
#include <linux/ahci_platform.h>
#include <linux/acpi.h>
#include <linux/pci_ids.h>
#include "ahci.h"

/* SGPIO Control Register definition
 *
 * Bit		Type		Description
 * 31		RW		OD7.2 (activity)
 * 30		RW		OD7.1 (locate)
 * 29		RW		OD7.0 (fault)
 * 28...8	RW		OD6.2...OD0.0 (3bits per port, 1 bit per LED)
 * 7		RO		SGPIO feature flag
 * 6:4		RO		Reserved
 * 3:0		RO		Number of ports (0 means no port supported)
 */
#define ACTIVITY_BIT_POS(x)		(8 + (3 * x))
#define LOCATE_BIT_POS(x)		(ACTIVITY_BIT_POS(x) + 1)
#define FAULT_BIT_POS(x)		(LOCATE_BIT_POS(x) + 1)

#define ACTIVITY_MASK			0x00010000
#define LOCATE_MASK			0x00080000
#define FAULT_MASK			0x00400000

#define DRV_NAME "ahci-seattle"

static ssize_t seattle_transmit_led_message(struct ata_port *ap, u32 state,
					    ssize_t size);

struct seattle_plat_data {
	void __iomem *sgpio_ctrl;
};

static struct ata_port_operations ahci_port_ops = {
	.inherits		= &ahci_ops,
};

static const struct ata_port_info ahci_port_info = {
	.flags		= AHCI_FLAG_COMMON,
	.pio_mask	= ATA_PIO4,
	.udma_mask	= ATA_UDMA6,
	.port_ops	= &ahci_port_ops,
};

static struct ata_port_operations ahci_seattle_ops = {
	.inherits		= &ahci_ops,
	.transmit_led_message   = seattle_transmit_led_message,
};

static const struct ata_port_info ahci_port_seattle_info = {
	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_EM | ATA_FLAG_SW_ACTIVITY,
	.link_flags	= ATA_LFLAG_SW_ACTIVITY,
	.pio_mask	= ATA_PIO4,
	.udma_mask	= ATA_UDMA6,
	.port_ops	= &ahci_seattle_ops,
};

static struct scsi_host_template ahci_platform_sht = {
	AHCI_SHT(DRV_NAME),
};

static ssize_t seattle_transmit_led_message(struct ata_port *ap, u32 state,
					    ssize_t size)
{
	struct ahci_host_priv *hpriv = ap->host->private_data;
	struct ahci_port_priv *pp = ap->private_data;
	struct seattle_plat_data *plat_data = hpriv->plat_data;
	unsigned long flags;
	int pmp;
	struct ahci_em_priv *emp;
	u32 val;

	/* get the slot number from the message */
	pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8;
	if (pmp >= EM_MAX_SLOTS)
		return -EINVAL;
	emp = &pp->em_priv[pmp];

	val = ioread32(plat_data->sgpio_ctrl);
	if (state & ACTIVITY_MASK)
		val |= 1 << ACTIVITY_BIT_POS((ap->port_no));
	else
		val &= ~(1 << ACTIVITY_BIT_POS((ap->port_no)));

	if (state & LOCATE_MASK)
		val |= 1 << LOCATE_BIT_POS((ap->port_no));
	else
		val &= ~(1 << LOCATE_BIT_POS((ap->port_no)));

	if (state & FAULT_MASK)
		val |= 1 << FAULT_BIT_POS((ap->port_no));
	else
		val &= ~(1 << FAULT_BIT_POS((ap->port_no)));

	iowrite32(val, plat_data->sgpio_ctrl);

	spin_lock_irqsave(ap->lock, flags);

	/* save off new led state for port/slot */
	emp->led_state = state;

	spin_unlock_irqrestore(ap->lock, flags);

	return size;
}

static const struct ata_port_info *ahci_seattle_get_port_info(
		struct platform_device *pdev, struct ahci_host_priv *hpriv)
{
	struct device *dev = &pdev->dev;
	struct seattle_plat_data *plat_data;
	u32 val;

	plat_data = devm_kzalloc(dev, sizeof(*plat_data), GFP_KERNEL);
	if (!plat_data)
		return &ahci_port_info;

	plat_data->sgpio_ctrl = devm_ioremap_resource(dev,
			      platform_get_resource(pdev, IORESOURCE_MEM, 1));
	if (IS_ERR(plat_data->sgpio_ctrl))
		return &ahci_port_info;

	val = ioread32(plat_data->sgpio_ctrl);

	if (!(val & 0xf))
		return &ahci_port_info;

	hpriv->em_loc = 0;
	hpriv->em_buf_sz = 4;
	hpriv->em_msg_type = EM_MSG_TYPE_LED;
	hpriv->plat_data = plat_data;

	dev_info(dev, "SGPIO LED control is enabled.\n");
	return &ahci_port_seattle_info;
}

static int ahci_seattle_probe(struct platform_device *pdev)
{
	int rc;
	struct ahci_host_priv *hpriv;

	hpriv = ahci_platform_get_resources(pdev, 0);
	if (IS_ERR(hpriv))
		return PTR_ERR(hpriv);

	rc = ahci_platform_enable_resources(hpriv);
	if (rc)
		return rc;

	rc = ahci_platform_init_host(pdev, hpriv,
				     ahci_seattle_get_port_info(pdev, hpriv),
				     &ahci_platform_sht);
	if (rc)
		goto disable_resources;

	return 0;
disable_resources:
	ahci_platform_disable_resources(hpriv);
	return rc;
}

static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend,
			 ahci_platform_resume);

static const struct acpi_device_id ahci_acpi_match[] = {
	{ "AMDI0600", 0 },
	{}
};
MODULE_DEVICE_TABLE(acpi, ahci_acpi_match);

static struct platform_driver ahci_seattle_driver = {
	.probe = ahci_seattle_probe,
	.remove = ata_platform_remove_one,
	.driver = {
		.name = DRV_NAME,
		.acpi_match_table = ahci_acpi_match,
		.pm = &ahci_pm_ops,
	},
};
module_platform_driver(ahci_seattle_driver);

MODULE_DESCRIPTION("Seattle AHCI SATA platform driver");
MODULE_AUTHOR("Brijesh Singh <brijesh.singh@amd.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
