/*
 * drivers/ata/ahci_tegra.c
 *
 * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
 *
 * Author:
 *	Mikko Perttunen <mperttunen@nvidia.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 *
 */

#include <linux/ahci_platform.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>

#include <soc/tegra/fuse.h>
#include <soc/tegra/pmc.h>

#include "ahci.h"

#define DRV_NAME "tegra-ahci"

#define SATA_CONFIGURATION_0				0x180
#define SATA_CONFIGURATION_0_EN_FPCI			BIT(0)
#define SATA_CONFIGURATION_0_CLK_OVERRIDE			BIT(31)

#define SCFG_OFFSET					0x1000

#define T_SATA0_CFG_1					0x04
#define T_SATA0_CFG_1_IO_SPACE				BIT(0)
#define T_SATA0_CFG_1_MEMORY_SPACE			BIT(1)
#define T_SATA0_CFG_1_BUS_MASTER			BIT(2)
#define T_SATA0_CFG_1_SERR				BIT(8)

#define T_SATA0_CFG_9					0x24
#define T_SATA0_CFG_9_BASE_ADDRESS			0x40020000

#define SATA_FPCI_BAR5					0x94
#define SATA_FPCI_BAR5_START_MASK			(0xfffffff << 4)
#define SATA_FPCI_BAR5_START				(0x0040020 << 4)
#define SATA_FPCI_BAR5_ACCESS_TYPE			(0x1)

#define SATA_INTR_MASK					0x188
#define SATA_INTR_MASK_IP_INT_MASK			BIT(16)

#define T_SATA0_CFG_35					0x94
#define T_SATA0_CFG_35_IDP_INDEX_MASK			(0x7ff << 2)
#define T_SATA0_CFG_35_IDP_INDEX			(0x2a << 2)

#define T_SATA0_AHCI_IDP1				0x98
#define T_SATA0_AHCI_IDP1_DATA				(0x400040)

#define T_SATA0_CFG_PHY_1				0x12c
#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN			BIT(23)
#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)

#define T_SATA0_NVOOB                                   0x114
#define T_SATA0_NVOOB_COMMA_CNT_MASK                    (0xff << 16)
#define T_SATA0_NVOOB_COMMA_CNT                         (0x07 << 16)
#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK          (0x3 << 24)
#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 24)
#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK        (0x3 << 26)
#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH             (0x3 << 26)

#define T_SATA_CFG_PHY_0                                0x120
#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD     BIT(11)
#define T_SATA_CFG_PHY_0_MASK_SQUELCH                   BIT(24)

#define T_SATA0_CFG2NVOOB_2				0x134
#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK	(0x1ff << 18)
#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW	(0xc << 18)

#define T_SATA0_AHCI_HBA_CAP_BKDR			0x300
#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP	BIT(13)
#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP	BIT(14)
#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP			BIT(26)
#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM		BIT(17)
#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ			BIT(30)

#define T_SATA0_BKDOOR_CC				0x4a4
#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK		(0xffff << 16)
#define T_SATA0_BKDOOR_CC_CLASS_CODE			(0x0106 << 16)
#define T_SATA0_BKDOOR_CC_PROG_IF_MASK			(0xff << 8)
#define T_SATA0_BKDOOR_CC_PROG_IF			(0x01 << 8)

#define T_SATA0_CFG_SATA				0x54c
#define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN		BIT(12)

#define T_SATA0_CFG_MISC				0x550

#define T_SATA0_INDEX					0x680

#define T_SATA0_CHX_PHY_CTRL1_GEN1			0x690
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK		0xff
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT		0
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK		(0xff << 8)
#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT	8

#define T_SATA0_CHX_PHY_CTRL1_GEN2			0x694
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK		0xff
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT		0
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK		(0xff << 12)
#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT	12

#define T_SATA0_CHX_PHY_CTRL2				0x69c
#define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1		0x23

#define T_SATA0_CHX_PHY_CTRL11				0x6d0
#define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ		(0x2800 << 16)

#define T_SATA0_CHX_PHY_CTRL17_0			0x6e8
#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1	0x55010000
#define T_SATA0_CHX_PHY_CTRL18_0			0x6ec
#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2	0x55010000
#define T_SATA0_CHX_PHY_CTRL20_0			0x6f4
#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1	0x1
#define T_SATA0_CHX_PHY_CTRL21_0			0x6f8
#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2	0x1

/* AUX Registers */
#define SATA_AUX_MISC_CNTL_1_0				0x8
#define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE		BIT(17)
#define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT		BIT(13)
#define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT		BIT(15)

#define SATA_AUX_RX_STAT_INT_0				0xc
#define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP		BIT(7)

#define SATA_AUX_SPARE_CFG0_0				0x18
#define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID	BIT(14)

#define FUSE_SATA_CALIB					0x124
#define FUSE_SATA_CALIB_MASK				0x3

struct sata_pad_calibration {
	u8 gen1_tx_amp;
	u8 gen1_tx_peak;
	u8 gen2_tx_amp;
	u8 gen2_tx_peak;
};

static const struct sata_pad_calibration tegra124_pad_calibration[] = {
	{0x18, 0x04, 0x18, 0x0a},
	{0x0e, 0x04, 0x14, 0x0a},
	{0x0e, 0x07, 0x1a, 0x0e},
	{0x14, 0x0e, 0x1a, 0x0e},
};

struct tegra_ahci_ops {
	int (*init)(struct ahci_host_priv *hpriv);
};

struct tegra_ahci_soc {
	const char *const		*supply_names;
	u32				num_supplies;
	bool				supports_devslp;
	const struct tegra_ahci_ops	*ops;
};

struct tegra_ahci_priv {
	struct platform_device	   *pdev;
	void __iomem		   *sata_regs;
	void __iomem		   *sata_aux_regs;
	struct reset_control	   *sata_rst;
	struct reset_control	   *sata_oob_rst;
	struct reset_control	   *sata_cold_rst;
	/* Needs special handling, cannot use ahci_platform */
	struct clk		   *sata_clk;
	struct regulator_bulk_data *supplies;
	const struct tegra_ahci_soc *soc;
};

static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv)
{
	struct tegra_ahci_priv *tegra = hpriv->plat_data;
	u32 val;

	if (tegra->sata_aux_regs && !tegra->soc->supports_devslp) {
		val = readl(tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
		val &= ~SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT;
		writel(val, tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
	}
}

static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
{
	struct tegra_ahci_priv *tegra = hpriv->plat_data;
	struct sata_pad_calibration calib;
	int ret;
	u32 val;

	/* Pad calibration */
	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
	if (ret)
		return ret;

	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];

	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);

	val = readl(tegra->sata_regs +
		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
	val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
	val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
	writel(val, tegra->sata_regs + SCFG_OFFSET +
	       T_SATA0_CHX_PHY_CTRL1_GEN1);

	val = readl(tegra->sata_regs +
		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
	val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
	val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
	writel(val, tegra->sata_regs + SCFG_OFFSET +
	       T_SATA0_CHX_PHY_CTRL1_GEN2);

	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);

	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);

	return 0;
}

static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
{
	struct tegra_ahci_priv *tegra = hpriv->plat_data;
	int ret;

	ret = regulator_bulk_enable(tegra->soc->num_supplies,
				    tegra->supplies);
	if (ret)
		return ret;

	ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
						tegra->sata_clk,
						tegra->sata_rst);
	if (ret)
		goto disable_regulators;

	reset_control_assert(tegra->sata_oob_rst);
	reset_control_assert(tegra->sata_cold_rst);

	ret = ahci_platform_enable_resources(hpriv);
	if (ret)
		goto disable_power;

	reset_control_deassert(tegra->sata_cold_rst);
	reset_control_deassert(tegra->sata_oob_rst);

	return 0;

disable_power:
	clk_disable_unprepare(tegra->sata_clk);

	tegra_powergate_power_off(TEGRA_POWERGATE_SATA);

disable_regulators:
	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);

	return ret;
}

static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
{
	struct tegra_ahci_priv *tegra = hpriv->plat_data;

	ahci_platform_disable_resources(hpriv);

	reset_control_assert(tegra->sata_rst);
	reset_control_assert(tegra->sata_oob_rst);
	reset_control_assert(tegra->sata_cold_rst);

	clk_disable_unprepare(tegra->sata_clk);
	tegra_powergate_power_off(TEGRA_POWERGATE_SATA);

	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
}

static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
{
	struct tegra_ahci_priv *tegra = hpriv->plat_data;
	int ret;
	u32 val;

	ret = tegra_ahci_power_on(hpriv);
	if (ret) {
		dev_err(&tegra->pdev->dev,
			"failed to power on AHCI controller: %d\n", ret);
		return ret;
	}

	/*
	 * Program the following SATA IPFS registers to allow SW accesses to
	 * SATA's MMIO register range.
	 */
	val = readl(tegra->sata_regs + SATA_FPCI_BAR5);
	val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE);
	val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE;
	writel(val, tegra->sata_regs + SATA_FPCI_BAR5);

	/* Program the following SATA IPFS register to enable the SATA */
	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
	val |= SATA_CONFIGURATION_0_EN_FPCI;
	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);

	/* Electrical settings for better link stability */
	val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0);
	val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0);
	val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0);
	val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0);

	/* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */

	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
	val |= T_SATA_CFG_PHY_0_MASK_SQUELCH;
	val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);

	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
	val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK |
		 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
	val |= (T_SATA0_NVOOB_COMMA_CNT |
		T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
		T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);

	/*
	 * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns
	 */
	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
	val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
	val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);

	if (tegra->soc->ops && tegra->soc->ops->init)
		tegra->soc->ops->init(hpriv);

	/*
	 * Program the following SATA configuration registers to
	 * initialize SATA
	 */
	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
	val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR);
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
	val = T_SATA0_CFG_9_BASE_ADDRESS;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);

	/* Program Class Code and Programming interface for SATA */
	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
	val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);

	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
	val &=
	    ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK |
	      T_SATA0_BKDOOR_CC_PROG_IF_MASK);
	val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);

	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
	val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);

	/* Enabling LPM capabilities through Backdoor Programming */
	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
	val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP |
		T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP |
		T_SATA0_AHCI_HBA_CAP_BKDR_SALP |
		T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM);
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);

	/* SATA Second Level Clock Gating configuration
	 * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane
	 * IDDQ Signals
	 */
	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
	val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK;
	val |= T_SATA0_CFG_35_IDP_INDEX;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);

	val = T_SATA0_AHCI_IDP1_DATA;
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1);

	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
	val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN |
		T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN);
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);

	/* Enabling IPFS Clock Gating */
	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
	val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE;
	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);

	tegra_ahci_handle_quirks(hpriv);

	/* Unmask SATA interrupts */

	val = readl(tegra->sata_regs + SATA_INTR_MASK);
	val |= SATA_INTR_MASK_IP_INT_MASK;
	writel(val, tegra->sata_regs + SATA_INTR_MASK);

	return 0;
}

static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
{
	tegra_ahci_power_off(hpriv);
}

static void tegra_ahci_host_stop(struct ata_host *host)
{
	struct ahci_host_priv *hpriv = host->private_data;

	tegra_ahci_controller_deinit(hpriv);
}

static struct ata_port_operations ahci_tegra_port_ops = {
	.inherits	= &ahci_ops,
	.host_stop	= tegra_ahci_host_stop,
};

static const struct ata_port_info ahci_tegra_port_info = {
	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
	.pio_mask	= ATA_PIO4,
	.udma_mask	= ATA_UDMA6,
	.port_ops	= &ahci_tegra_port_ops,
};

static const char *const tegra124_supply_names[] = {
	"avdd", "hvdd", "vddio", "target-5v", "target-12v"
};

static const struct tegra_ahci_ops tegra124_ahci_ops = {
	.init = tegra124_ahci_init,
};

static const struct tegra_ahci_soc tegra124_ahci_soc = {
	.supply_names = tegra124_supply_names,
	.num_supplies = ARRAY_SIZE(tegra124_supply_names),
	.supports_devslp = false,
	.ops = &tegra124_ahci_ops,
};

static const struct tegra_ahci_soc tegra210_ahci_soc = {
	.supports_devslp = false,
};

static const struct of_device_id tegra_ahci_of_match[] = {
	{
		.compatible = "nvidia,tegra124-ahci",
		.data = &tegra124_ahci_soc
	},
	{
		.compatible = "nvidia,tegra210-ahci",
		.data = &tegra210_ahci_soc
	},
	{}
};
MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);

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

static int tegra_ahci_probe(struct platform_device *pdev)
{
	struct ahci_host_priv *hpriv;
	struct tegra_ahci_priv *tegra;
	struct resource *res;
	int ret;
	unsigned int i;

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

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

	hpriv->plat_data = tegra;

	tegra->pdev = pdev;
	tegra->soc = of_device_get_match_data(&pdev->dev);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(tegra->sata_regs))
		return PTR_ERR(tegra->sata_regs);

	/*
	 * AUX registers is optional.
	 */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	if (res) {
		tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(tegra->sata_aux_regs))
			return PTR_ERR(tegra->sata_aux_regs);
	}

	tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
	if (IS_ERR(tegra->sata_rst)) {
		dev_err(&pdev->dev, "Failed to get sata reset\n");
		return PTR_ERR(tegra->sata_rst);
	}

	tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, "sata-oob");
	if (IS_ERR(tegra->sata_oob_rst)) {
		dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
		return PTR_ERR(tegra->sata_oob_rst);
	}

	tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
	if (IS_ERR(tegra->sata_cold_rst)) {
		dev_err(&pdev->dev, "Failed to get sata-cold reset\n");
		return PTR_ERR(tegra->sata_cold_rst);
	}

	tegra->sata_clk = devm_clk_get(&pdev->dev, "sata");
	if (IS_ERR(tegra->sata_clk)) {
		dev_err(&pdev->dev, "Failed to get sata clock\n");
		return PTR_ERR(tegra->sata_clk);
	}

	tegra->supplies = devm_kcalloc(&pdev->dev,
				       tegra->soc->num_supplies,
				       sizeof(*tegra->supplies), GFP_KERNEL);
	if (!tegra->supplies)
		return -ENOMEM;

	for (i = 0; i < tegra->soc->num_supplies; i++)
		tegra->supplies[i].supply = tegra->soc->supply_names[i];

	ret = devm_regulator_bulk_get(&pdev->dev,
				      tegra->soc->num_supplies,
				      tegra->supplies);
	if (ret) {
		dev_err(&pdev->dev, "Failed to get regulators\n");
		return ret;
	}

	ret = tegra_ahci_controller_init(hpriv);
	if (ret)
		return ret;

	ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
				      &ahci_platform_sht);
	if (ret)
		goto deinit_controller;

	return 0;

deinit_controller:
	tegra_ahci_controller_deinit(hpriv);

	return ret;
};

static struct platform_driver tegra_ahci_driver = {
	.probe = tegra_ahci_probe,
	.remove = ata_platform_remove_one,
	.driver = {
		.name = DRV_NAME,
		.of_match_table = tegra_ahci_of_match,
	},
	/* LP0 suspend support not implemented */
};
module_platform_driver(tegra_ahci_driver);

MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
MODULE_DESCRIPTION("Tegra AHCI SATA driver");
MODULE_LICENSE("GPL v2");
