/*
 * Copyright (C) 2012 STMicroelectronics Limited
 *
 * Authors: Francesco Virlinzi <francesco.virlinzi@st.com>
 *	    Alexandre Torgue <alexandre.torgue@st.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/ahci_platform.h>
#include <linux/libata.h>
#include <linux/reset.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>

#include "ahci.h"

#define DRV_NAME  "st_ahci"

#define ST_AHCI_OOBR			0xbc
#define ST_AHCI_OOBR_WE			BIT(31)
#define ST_AHCI_OOBR_CWMIN_SHIFT	24
#define ST_AHCI_OOBR_CWMAX_SHIFT	16
#define ST_AHCI_OOBR_CIMIN_SHIFT	8
#define ST_AHCI_OOBR_CIMAX_SHIFT	0

struct st_ahci_drv_data {
	struct platform_device *ahci;
	struct reset_control *pwr;
	struct reset_control *sw_rst;
	struct reset_control *pwr_rst;
	struct ahci_host_priv *hpriv;
};

static void st_ahci_configure_oob(void __iomem *mmio)
{
	unsigned long old_val, new_val;

	new_val = (0x02 << ST_AHCI_OOBR_CWMIN_SHIFT) |
		  (0x04 << ST_AHCI_OOBR_CWMAX_SHIFT) |
		  (0x08 << ST_AHCI_OOBR_CIMIN_SHIFT) |
		  (0x0C << ST_AHCI_OOBR_CIMAX_SHIFT);

	old_val = readl(mmio + ST_AHCI_OOBR);
	writel(old_val | ST_AHCI_OOBR_WE, mmio + ST_AHCI_OOBR);
	writel(new_val | ST_AHCI_OOBR_WE, mmio + ST_AHCI_OOBR);
	writel(new_val, mmio + ST_AHCI_OOBR);
}

static int st_ahci_deassert_resets(struct device *dev)
{
	struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
	int err;

	if (drv_data->pwr) {
		err = reset_control_deassert(drv_data->pwr);
		if (err) {
			dev_err(dev, "unable to bring out of pwrdwn\n");
			return err;
		}
	}

	if (drv_data->sw_rst) {
		err = reset_control_deassert(drv_data->sw_rst);
		if (err) {
			dev_err(dev, "unable to bring out of sw-rst\n");
			return err;
		}
	}

	if (drv_data->pwr_rst) {
		err = reset_control_deassert(drv_data->pwr_rst);
		if (err) {
			dev_err(dev, "unable to bring out of pwr-rst\n");
			return err;
		}
	}

	return 0;
}

static void st_ahci_host_stop(struct ata_host *host)
{
	struct ahci_host_priv *hpriv = host->private_data;
	struct device *dev = host->dev;
	struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
	int err;

	if (drv_data->pwr) {
		err = reset_control_assert(drv_data->pwr);
		if (err)
			dev_err(dev, "unable to pwrdwn\n");
	}

	ahci_platform_disable_resources(hpriv);
}

static int st_ahci_probe_resets(struct platform_device *pdev)
{
	struct st_ahci_drv_data *drv_data = platform_get_drvdata(pdev);

	drv_data->pwr = devm_reset_control_get(&pdev->dev, "pwr-dwn");
	if (IS_ERR(drv_data->pwr)) {
		dev_info(&pdev->dev, "power reset control not defined\n");
		drv_data->pwr = NULL;
	}

	drv_data->sw_rst = devm_reset_control_get(&pdev->dev, "sw-rst");
	if (IS_ERR(drv_data->sw_rst)) {
		dev_info(&pdev->dev, "soft reset control not defined\n");
		drv_data->sw_rst = NULL;
	}

	drv_data->pwr_rst = devm_reset_control_get(&pdev->dev, "pwr-rst");
	if (IS_ERR(drv_data->pwr_rst)) {
		dev_dbg(&pdev->dev, "power soft reset control not defined\n");
		drv_data->pwr_rst = NULL;
	}

	return st_ahci_deassert_resets(&pdev->dev);
}

static struct ata_port_operations st_ahci_port_ops = {
	.inherits	= &ahci_platform_ops,
	.host_stop	= st_ahci_host_stop,
};

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

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

static int st_ahci_probe(struct platform_device *pdev)
{
	struct st_ahci_drv_data *drv_data;
	struct ahci_host_priv *hpriv;
	int err;

	drv_data = devm_kzalloc(&pdev->dev, sizeof(*drv_data), GFP_KERNEL);
	if (!drv_data)
		return -ENOMEM;

	platform_set_drvdata(pdev, drv_data);

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

	drv_data->hpriv = hpriv;

	err = st_ahci_probe_resets(pdev);
	if (err)
		return err;

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

	st_ahci_configure_oob(drv_data->hpriv->mmio);

	err = ahci_platform_init_host(pdev, hpriv, &st_ahci_port_info,
				      &ahci_platform_sht);
	if (err) {
		ahci_platform_disable_resources(hpriv);
		return err;
	}

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int st_ahci_suspend(struct device *dev)
{
	struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
	struct ahci_host_priv *hpriv = drv_data->hpriv;
	int err;

	err = ahci_platform_suspend_host(dev);
	if (err)
		return err;

	if (drv_data->pwr) {
		err = reset_control_assert(drv_data->pwr);
		if (err) {
			dev_err(dev, "unable to pwrdwn");
			return err;
		}
	}

	ahci_platform_disable_resources(hpriv);

	return 0;
}

static int st_ahci_resume(struct device *dev)
{
	struct st_ahci_drv_data *drv_data = dev_get_drvdata(dev);
	struct ahci_host_priv *hpriv = drv_data->hpriv;
	int err;

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

	err = st_ahci_deassert_resets(dev);
	if (err) {
		ahci_platform_disable_resources(hpriv);
		return err;
	}

	st_ahci_configure_oob(drv_data->hpriv->mmio);

	return ahci_platform_resume_host(dev);
}
#endif

static SIMPLE_DEV_PM_OPS(st_ahci_pm_ops, st_ahci_suspend, st_ahci_resume);

static const struct of_device_id st_ahci_match[] = {
	{ .compatible = "st,ahci", },
	{},
};
MODULE_DEVICE_TABLE(of, st_ahci_match);

static struct platform_driver st_ahci_driver = {
	.driver = {
		.name = DRV_NAME,
		.pm = &st_ahci_pm_ops,
		.of_match_table = of_match_ptr(st_ahci_match),
	},
	.probe = st_ahci_probe,
	.remove = ata_platform_remove_one,
};
module_platform_driver(st_ahci_driver);

MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
MODULE_AUTHOR("Francesco Virlinzi <francesco.virlinzi@st.com>");
MODULE_DESCRIPTION("STMicroelectronics SATA AHCI Driver");
MODULE_LICENSE("GPL v2");
