xref: /openbmc/linux/drivers/ata/ahci_tegra.c (revision 7f187e74)
19c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2ccfde508SMikko Perttunen /*
3ccfde508SMikko Perttunen  * drivers/ata/ahci_tegra.c
4ccfde508SMikko Perttunen  *
5ccfde508SMikko Perttunen  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
6ccfde508SMikko Perttunen  *
7ccfde508SMikko Perttunen  * Author:
8ccfde508SMikko Perttunen  *	Mikko Perttunen <mperttunen@nvidia.com>
9ccfde508SMikko Perttunen  */
10ccfde508SMikko Perttunen 
11ccfde508SMikko Perttunen #include <linux/ahci_platform.h>
12ccfde508SMikko Perttunen #include <linux/errno.h>
13ccfde508SMikko Perttunen #include <linux/kernel.h>
14ccfde508SMikko Perttunen #include <linux/module.h>
1561e6ae71SRob Herring #include <linux/of.h>
16ccfde508SMikko Perttunen #include <linux/platform_device.h>
17ccfde508SMikko Perttunen #include <linux/regulator/consumer.h>
18e327f115SMikko Perttunen #include <linux/reset.h>
19e327f115SMikko Perttunen 
20e327f115SMikko Perttunen #include <soc/tegra/fuse.h>
210e574077SMikko Perttunen #include <soc/tegra/pmc.h>
22e327f115SMikko Perttunen 
23ccfde508SMikko Perttunen #include "ahci.h"
24ccfde508SMikko Perttunen 
25018d5ef2SAkinobu Mita #define DRV_NAME "tegra-ahci"
26018d5ef2SAkinobu Mita 
27ccfde508SMikko Perttunen #define SATA_CONFIGURATION_0				0x180
2856337b55SPreetham Ramchandra #define SATA_CONFIGURATION_0_EN_FPCI			BIT(0)
2956337b55SPreetham Ramchandra #define SATA_CONFIGURATION_0_CLK_OVERRIDE			BIT(31)
30ccfde508SMikko Perttunen 
31ccfde508SMikko Perttunen #define SCFG_OFFSET					0x1000
32ccfde508SMikko Perttunen 
33ccfde508SMikko Perttunen #define T_SATA0_CFG_1					0x04
34ccfde508SMikko Perttunen #define T_SATA0_CFG_1_IO_SPACE				BIT(0)
35ccfde508SMikko Perttunen #define T_SATA0_CFG_1_MEMORY_SPACE			BIT(1)
36ccfde508SMikko Perttunen #define T_SATA0_CFG_1_BUS_MASTER			BIT(2)
37ccfde508SMikko Perttunen #define T_SATA0_CFG_1_SERR				BIT(8)
38ccfde508SMikko Perttunen 
39ccfde508SMikko Perttunen #define T_SATA0_CFG_9					0x24
4056337b55SPreetham Ramchandra #define T_SATA0_CFG_9_BASE_ADDRESS			0x40020000
41ccfde508SMikko Perttunen 
42ccfde508SMikko Perttunen #define SATA_FPCI_BAR5					0x94
4356337b55SPreetham Ramchandra #define SATA_FPCI_BAR5_START_MASK			(0xfffffff << 4)
4456337b55SPreetham Ramchandra #define SATA_FPCI_BAR5_START				(0x0040020 << 4)
4556337b55SPreetham Ramchandra #define SATA_FPCI_BAR5_ACCESS_TYPE			(0x1)
46ccfde508SMikko Perttunen 
47ccfde508SMikko Perttunen #define SATA_INTR_MASK					0x188
48ccfde508SMikko Perttunen #define SATA_INTR_MASK_IP_INT_MASK			BIT(16)
49ccfde508SMikko Perttunen 
5056337b55SPreetham Ramchandra #define T_SATA0_CFG_35					0x94
5156337b55SPreetham Ramchandra #define T_SATA0_CFG_35_IDP_INDEX_MASK			(0x7ff << 2)
5256337b55SPreetham Ramchandra #define T_SATA0_CFG_35_IDP_INDEX			(0x2a << 2)
5356337b55SPreetham Ramchandra 
5456337b55SPreetham Ramchandra #define T_SATA0_AHCI_IDP1				0x98
5556337b55SPreetham Ramchandra #define T_SATA0_AHCI_IDP1_DATA				(0x400040)
5656337b55SPreetham Ramchandra 
5756337b55SPreetham Ramchandra #define T_SATA0_CFG_PHY_1				0x12c
5856337b55SPreetham Ramchandra #define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN			BIT(23)
5956337b55SPreetham Ramchandra #define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
6056337b55SPreetham Ramchandra 
6156337b55SPreetham Ramchandra #define T_SATA0_NVOOB                                   0x114
6256337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK          (0x3 << 24)
6356337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 24)
6456337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK        (0x3 << 26)
6556337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH             (0x3 << 26)
6656337b55SPreetham Ramchandra 
6756337b55SPreetham Ramchandra #define T_SATA_CFG_PHY_0                                0x120
6856337b55SPreetham Ramchandra #define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD     BIT(11)
6956337b55SPreetham Ramchandra #define T_SATA_CFG_PHY_0_MASK_SQUELCH                   BIT(24)
7056337b55SPreetham Ramchandra 
7156337b55SPreetham Ramchandra #define T_SATA0_CFG2NVOOB_2				0x134
7256337b55SPreetham Ramchandra #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK	(0x1ff << 18)
7356337b55SPreetham Ramchandra #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW	(0xc << 18)
7456337b55SPreetham Ramchandra 
75ccfde508SMikko Perttunen #define T_SATA0_AHCI_HBA_CAP_BKDR			0x300
7656337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP	BIT(13)
7756337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP	BIT(14)
7856337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SALP			BIT(26)
7956337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM		BIT(17)
8056337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ			BIT(30)
81ccfde508SMikko Perttunen 
82ccfde508SMikko Perttunen #define T_SATA0_BKDOOR_CC				0x4a4
8356337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK		(0xffff << 16)
8456337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_CLASS_CODE			(0x0106 << 16)
8556337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_PROG_IF_MASK			(0xff << 8)
8656337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_PROG_IF			(0x01 << 8)
87ccfde508SMikko Perttunen 
88ccfde508SMikko Perttunen #define T_SATA0_CFG_SATA				0x54c
89ccfde508SMikko Perttunen #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN		BIT(12)
90ccfde508SMikko Perttunen 
91ccfde508SMikko Perttunen #define T_SATA0_CFG_MISC				0x550
92ccfde508SMikko Perttunen 
93ccfde508SMikko Perttunen #define T_SATA0_INDEX					0x680
94ccfde508SMikko Perttunen 
95ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1			0x690
96ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK		0xff
97ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT		0
98ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK		(0xff << 8)
99ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT	8
100ccfde508SMikko Perttunen 
101ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2			0x694
102ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK		0xff
103ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT		0
104ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK		(0xff << 12)
105ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT	12
106ccfde508SMikko Perttunen 
107ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL2				0x69c
108ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1		0x23
109ccfde508SMikko Perttunen 
110ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL11				0x6d0
111ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ		(0x2800 << 16)
112ccfde508SMikko Perttunen 
11356337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL17_0			0x6e8
11456337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1	0x55010000
11556337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL18_0			0x6ec
11656337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2	0x55010000
11756337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL20_0			0x6f4
11856337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1	0x1
11956337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL21_0			0x6f8
12056337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2	0x1
12156337b55SPreetham Ramchandra 
12256337b55SPreetham Ramchandra /* AUX Registers */
12356337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0				0x8
12456337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE		BIT(17)
12556337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT		BIT(13)
12656337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT		BIT(15)
12756337b55SPreetham Ramchandra 
12856337b55SPreetham Ramchandra #define SATA_AUX_RX_STAT_INT_0				0xc
12956337b55SPreetham Ramchandra #define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP		BIT(7)
13056337b55SPreetham Ramchandra 
13156337b55SPreetham Ramchandra #define SATA_AUX_SPARE_CFG0_0				0x18
13256337b55SPreetham Ramchandra #define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID	BIT(14)
13356337b55SPreetham Ramchandra 
134ccfde508SMikko Perttunen #define FUSE_SATA_CALIB					0x124
135ccfde508SMikko Perttunen #define FUSE_SATA_CALIB_MASK				0x3
136ccfde508SMikko Perttunen 
137ccfde508SMikko Perttunen struct sata_pad_calibration {
138ccfde508SMikko Perttunen 	u8 gen1_tx_amp;
139ccfde508SMikko Perttunen 	u8 gen1_tx_peak;
140ccfde508SMikko Perttunen 	u8 gen2_tx_amp;
141ccfde508SMikko Perttunen 	u8 gen2_tx_peak;
142ccfde508SMikko Perttunen };
143ccfde508SMikko Perttunen 
144ccfde508SMikko Perttunen static const struct sata_pad_calibration tegra124_pad_calibration[] = {
145ccfde508SMikko Perttunen 	{0x18, 0x04, 0x18, 0x0a},
146ccfde508SMikko Perttunen 	{0x0e, 0x04, 0x14, 0x0a},
147ccfde508SMikko Perttunen 	{0x0e, 0x07, 0x1a, 0x0e},
148ccfde508SMikko Perttunen 	{0x14, 0x0e, 0x1a, 0x0e},
149ccfde508SMikko Perttunen };
150ccfde508SMikko Perttunen 
15156337b55SPreetham Ramchandra struct tegra_ahci_ops {
15256337b55SPreetham Ramchandra 	int (*init)(struct ahci_host_priv *hpriv);
15356337b55SPreetham Ramchandra };
15456337b55SPreetham Ramchandra 
155868ed731SSowjanya Komatineni struct tegra_ahci_regs {
156868ed731SSowjanya Komatineni 	unsigned int nvoob_comma_cnt_mask;
157868ed731SSowjanya Komatineni 	unsigned int nvoob_comma_cnt_val;
158868ed731SSowjanya Komatineni };
159868ed731SSowjanya Komatineni 
16056337b55SPreetham Ramchandra struct tegra_ahci_soc {
16143ee827bSPreetham Ramchandra 	const char *const		*supply_names;
16243ee827bSPreetham Ramchandra 	u32				num_supplies;
163502717ccSPreetham Ramchandra 	bool				supports_devslp;
164868ed731SSowjanya Komatineni 	bool				has_sata_oob_rst;
16556337b55SPreetham Ramchandra 	const struct tegra_ahci_ops	*ops;
166868ed731SSowjanya Komatineni 	const struct tegra_ahci_regs	*regs;
16756337b55SPreetham Ramchandra };
16856337b55SPreetham Ramchandra 
169ccfde508SMikko Perttunen struct tegra_ahci_priv {
170ccfde508SMikko Perttunen 	struct platform_device	   *pdev;
171ccfde508SMikko Perttunen 	void __iomem		   *sata_regs;
172502717ccSPreetham Ramchandra 	void __iomem		   *sata_aux_regs;
173ccfde508SMikko Perttunen 	struct reset_control	   *sata_rst;
174ccfde508SMikko Perttunen 	struct reset_control	   *sata_oob_rst;
175ccfde508SMikko Perttunen 	struct reset_control	   *sata_cold_rst;
176ccfde508SMikko Perttunen 	/* Needs special handling, cannot use ahci_platform */
177ccfde508SMikko Perttunen 	struct clk		   *sata_clk;
17843ee827bSPreetham Ramchandra 	struct regulator_bulk_data *supplies;
17956337b55SPreetham Ramchandra 	const struct tegra_ahci_soc *soc;
180ccfde508SMikko Perttunen };
181ccfde508SMikko Perttunen 
tegra_ahci_handle_quirks(struct ahci_host_priv * hpriv)182502717ccSPreetham Ramchandra static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv)
183502717ccSPreetham Ramchandra {
184502717ccSPreetham Ramchandra 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
185502717ccSPreetham Ramchandra 	u32 val;
186502717ccSPreetham Ramchandra 
187502717ccSPreetham Ramchandra 	if (tegra->sata_aux_regs && !tegra->soc->supports_devslp) {
188502717ccSPreetham Ramchandra 		val = readl(tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
189502717ccSPreetham Ramchandra 		val &= ~SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT;
190502717ccSPreetham Ramchandra 		writel(val, tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
191502717ccSPreetham Ramchandra 	}
192502717ccSPreetham Ramchandra }
193502717ccSPreetham Ramchandra 
tegra124_ahci_init(struct ahci_host_priv * hpriv)19456337b55SPreetham Ramchandra static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
19556337b55SPreetham Ramchandra {
19656337b55SPreetham Ramchandra 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
19756337b55SPreetham Ramchandra 	struct sata_pad_calibration calib;
19856337b55SPreetham Ramchandra 	int ret;
19956337b55SPreetham Ramchandra 	u32 val;
20056337b55SPreetham Ramchandra 
20156337b55SPreetham Ramchandra 	/* Pad calibration */
20256337b55SPreetham Ramchandra 	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
20356337b55SPreetham Ramchandra 	if (ret)
20456337b55SPreetham Ramchandra 		return ret;
20556337b55SPreetham Ramchandra 
20656337b55SPreetham Ramchandra 	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
20756337b55SPreetham Ramchandra 
20856337b55SPreetham Ramchandra 	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
20956337b55SPreetham Ramchandra 
21056337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs +
21156337b55SPreetham Ramchandra 		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
21256337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
21356337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
21456337b55SPreetham Ramchandra 	val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
21556337b55SPreetham Ramchandra 	val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
21656337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET +
21756337b55SPreetham Ramchandra 	       T_SATA0_CHX_PHY_CTRL1_GEN1);
21856337b55SPreetham Ramchandra 
21956337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs +
22056337b55SPreetham Ramchandra 		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
22156337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
22256337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
22356337b55SPreetham Ramchandra 	val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
22456337b55SPreetham Ramchandra 	val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
22556337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET +
22656337b55SPreetham Ramchandra 	       T_SATA0_CHX_PHY_CTRL1_GEN2);
22756337b55SPreetham Ramchandra 
22856337b55SPreetham Ramchandra 	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
22956337b55SPreetham Ramchandra 	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
23056337b55SPreetham Ramchandra 	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
23156337b55SPreetham Ramchandra 	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
23256337b55SPreetham Ramchandra 
23356337b55SPreetham Ramchandra 	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
23456337b55SPreetham Ramchandra 
23556337b55SPreetham Ramchandra 	return 0;
23656337b55SPreetham Ramchandra }
23756337b55SPreetham Ramchandra 
tegra_ahci_power_on(struct ahci_host_priv * hpriv)238ccfde508SMikko Perttunen static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
239ccfde508SMikko Perttunen {
240ccfde508SMikko Perttunen 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
241ccfde508SMikko Perttunen 	int ret;
242ccfde508SMikko Perttunen 
24343ee827bSPreetham Ramchandra 	ret = regulator_bulk_enable(tegra->soc->num_supplies,
244ccfde508SMikko Perttunen 				    tegra->supplies);
245ccfde508SMikko Perttunen 	if (ret)
246ccfde508SMikko Perttunen 		return ret;
247ccfde508SMikko Perttunen 
248868ed731SSowjanya Komatineni 	if (!tegra->pdev->dev.pm_domain) {
249ccfde508SMikko Perttunen 		ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
250ccfde508SMikko Perttunen 							tegra->sata_clk,
251ccfde508SMikko Perttunen 							tegra->sata_rst);
252ccfde508SMikko Perttunen 		if (ret)
253ccfde508SMikko Perttunen 			goto disable_regulators;
254868ed731SSowjanya Komatineni 	}
255ccfde508SMikko Perttunen 
256ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_oob_rst);
257ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_cold_rst);
258ccfde508SMikko Perttunen 
259ccfde508SMikko Perttunen 	ret = ahci_platform_enable_resources(hpriv);
260ccfde508SMikko Perttunen 	if (ret)
261ccfde508SMikko Perttunen 		goto disable_power;
262ccfde508SMikko Perttunen 
263ccfde508SMikko Perttunen 	reset_control_deassert(tegra->sata_cold_rst);
264ccfde508SMikko Perttunen 	reset_control_deassert(tegra->sata_oob_rst);
265ccfde508SMikko Perttunen 
266ccfde508SMikko Perttunen 	return 0;
267ccfde508SMikko Perttunen 
268ccfde508SMikko Perttunen disable_power:
269ccfde508SMikko Perttunen 	clk_disable_unprepare(tegra->sata_clk);
270ccfde508SMikko Perttunen 
2718b625d01SSowjanya Komatineni 	if (!tegra->pdev->dev.pm_domain)
272ccfde508SMikko Perttunen 		tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
273ccfde508SMikko Perttunen 
274ccfde508SMikko Perttunen disable_regulators:
27543ee827bSPreetham Ramchandra 	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
276ccfde508SMikko Perttunen 
277ccfde508SMikko Perttunen 	return ret;
278ccfde508SMikko Perttunen }
279ccfde508SMikko Perttunen 
tegra_ahci_power_off(struct ahci_host_priv * hpriv)280ccfde508SMikko Perttunen static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
281ccfde508SMikko Perttunen {
282ccfde508SMikko Perttunen 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
283ccfde508SMikko Perttunen 
284ccfde508SMikko Perttunen 	ahci_platform_disable_resources(hpriv);
285ccfde508SMikko Perttunen 
286ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_rst);
287ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_oob_rst);
288ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_cold_rst);
289ccfde508SMikko Perttunen 
290ccfde508SMikko Perttunen 	clk_disable_unprepare(tegra->sata_clk);
2918b625d01SSowjanya Komatineni 	if (!tegra->pdev->dev.pm_domain)
292ccfde508SMikko Perttunen 		tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
293ccfde508SMikko Perttunen 
29443ee827bSPreetham Ramchandra 	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
295ccfde508SMikko Perttunen }
296ccfde508SMikko Perttunen 
tegra_ahci_controller_init(struct ahci_host_priv * hpriv)297ccfde508SMikko Perttunen static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
298ccfde508SMikko Perttunen {
299ccfde508SMikko Perttunen 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
300ccfde508SMikko Perttunen 	int ret;
30156337b55SPreetham Ramchandra 	u32 val;
302ccfde508SMikko Perttunen 
303ccfde508SMikko Perttunen 	ret = tegra_ahci_power_on(hpriv);
304ccfde508SMikko Perttunen 	if (ret) {
305ccfde508SMikko Perttunen 		dev_err(&tegra->pdev->dev,
306ccfde508SMikko Perttunen 			"failed to power on AHCI controller: %d\n", ret);
307ccfde508SMikko Perttunen 		return ret;
308ccfde508SMikko Perttunen 	}
309ccfde508SMikko Perttunen 
31056337b55SPreetham Ramchandra 	/*
31156337b55SPreetham Ramchandra 	 * Program the following SATA IPFS registers to allow SW accesses to
31256337b55SPreetham Ramchandra 	 * SATA's MMIO register range.
31356337b55SPreetham Ramchandra 	 */
31456337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SATA_FPCI_BAR5);
31556337b55SPreetham Ramchandra 	val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE);
31656337b55SPreetham Ramchandra 	val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE;
31756337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SATA_FPCI_BAR5);
31856337b55SPreetham Ramchandra 
31956337b55SPreetham Ramchandra 	/* Program the following SATA IPFS register to enable the SATA */
320ccfde508SMikko Perttunen 	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
32156337b55SPreetham Ramchandra 	val |= SATA_CONFIGURATION_0_EN_FPCI;
322ccfde508SMikko Perttunen 	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
323ccfde508SMikko Perttunen 
32456337b55SPreetham Ramchandra 	/* Electrical settings for better link stability */
32556337b55SPreetham Ramchandra 	val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1;
32656337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0);
32756337b55SPreetham Ramchandra 	val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2;
32856337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0);
32956337b55SPreetham Ramchandra 	val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1;
33056337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0);
33156337b55SPreetham Ramchandra 	val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2;
33256337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0);
333ccfde508SMikko Perttunen 
33456337b55SPreetham Ramchandra 	/* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */
335ccfde508SMikko Perttunen 
33656337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
33756337b55SPreetham Ramchandra 	val |= T_SATA_CFG_PHY_0_MASK_SQUELCH;
33856337b55SPreetham Ramchandra 	val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
33956337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
340ccfde508SMikko Perttunen 
34156337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
342868ed731SSowjanya Komatineni 	val &= ~(tegra->soc->regs->nvoob_comma_cnt_mask |
34356337b55SPreetham Ramchandra 		 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
34456337b55SPreetham Ramchandra 		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
345868ed731SSowjanya Komatineni 	val |= (tegra->soc->regs->nvoob_comma_cnt_val |
34656337b55SPreetham Ramchandra 		T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
34756337b55SPreetham Ramchandra 		T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
34856337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
349ccfde508SMikko Perttunen 
35056337b55SPreetham Ramchandra 	/*
35156337b55SPreetham Ramchandra 	 * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns
35256337b55SPreetham Ramchandra 	 */
35356337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
35456337b55SPreetham Ramchandra 	val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
35556337b55SPreetham Ramchandra 	val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
35656337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
357ccfde508SMikko Perttunen 
35856337b55SPreetham Ramchandra 	if (tegra->soc->ops && tegra->soc->ops->init)
35956337b55SPreetham Ramchandra 		tegra->soc->ops->init(hpriv);
360ccfde508SMikko Perttunen 
36156337b55SPreetham Ramchandra 	/*
36256337b55SPreetham Ramchandra 	 * Program the following SATA configuration registers to
36356337b55SPreetham Ramchandra 	 * initialize SATA
36456337b55SPreetham Ramchandra 	 */
36556337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
36656337b55SPreetham Ramchandra 	val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
36756337b55SPreetham Ramchandra 		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR);
36856337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
36956337b55SPreetham Ramchandra 	val = T_SATA0_CFG_9_BASE_ADDRESS;
37056337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
371ccfde508SMikko Perttunen 
37256337b55SPreetham Ramchandra 	/* Program Class Code and Programming interface for SATA */
373ccfde508SMikko Perttunen 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
374ccfde508SMikko Perttunen 	val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
375ccfde508SMikko Perttunen 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
376ccfde508SMikko Perttunen 
37756337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
37856337b55SPreetham Ramchandra 	val &=
37956337b55SPreetham Ramchandra 	    ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK |
38056337b55SPreetham Ramchandra 	      T_SATA0_BKDOOR_CC_PROG_IF_MASK);
38156337b55SPreetham Ramchandra 	val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF;
38256337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
383ccfde508SMikko Perttunen 
384ccfde508SMikko Perttunen 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
385ccfde508SMikko Perttunen 	val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
386ccfde508SMikko Perttunen 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
387ccfde508SMikko Perttunen 
38856337b55SPreetham Ramchandra 	/* Enabling LPM capabilities through Backdoor Programming */
38956337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
39056337b55SPreetham Ramchandra 	val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP |
39156337b55SPreetham Ramchandra 		T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP |
39256337b55SPreetham Ramchandra 		T_SATA0_AHCI_HBA_CAP_BKDR_SALP |
39356337b55SPreetham Ramchandra 		T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM);
39456337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
395ccfde508SMikko Perttunen 
39656337b55SPreetham Ramchandra 	/* SATA Second Level Clock Gating configuration
39756337b55SPreetham Ramchandra 	 * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane
39856337b55SPreetham Ramchandra 	 * IDDQ Signals
39956337b55SPreetham Ramchandra 	 */
40056337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
40156337b55SPreetham Ramchandra 	val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK;
40256337b55SPreetham Ramchandra 	val |= T_SATA0_CFG_35_IDP_INDEX;
40356337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
404ccfde508SMikko Perttunen 
40556337b55SPreetham Ramchandra 	val = T_SATA0_AHCI_IDP1_DATA;
40656337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1);
407ccfde508SMikko Perttunen 
40856337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
40956337b55SPreetham Ramchandra 	val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN |
41056337b55SPreetham Ramchandra 		T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN);
41156337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
412ccfde508SMikko Perttunen 
41356337b55SPreetham Ramchandra 	/* Enabling IPFS Clock Gating */
41456337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
41556337b55SPreetham Ramchandra 	val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE;
41656337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
41756337b55SPreetham Ramchandra 
418502717ccSPreetham Ramchandra 	tegra_ahci_handle_quirks(hpriv);
419ccfde508SMikko Perttunen 
420ccfde508SMikko Perttunen 	/* Unmask SATA interrupts */
421ccfde508SMikko Perttunen 
422ccfde508SMikko Perttunen 	val = readl(tegra->sata_regs + SATA_INTR_MASK);
423ccfde508SMikko Perttunen 	val |= SATA_INTR_MASK_IP_INT_MASK;
424ccfde508SMikko Perttunen 	writel(val, tegra->sata_regs + SATA_INTR_MASK);
425ccfde508SMikko Perttunen 
426ccfde508SMikko Perttunen 	return 0;
427ccfde508SMikko Perttunen }
428ccfde508SMikko Perttunen 
tegra_ahci_controller_deinit(struct ahci_host_priv * hpriv)429ccfde508SMikko Perttunen static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
430ccfde508SMikko Perttunen {
431ccfde508SMikko Perttunen 	tegra_ahci_power_off(hpriv);
432ccfde508SMikko Perttunen }
433ccfde508SMikko Perttunen 
tegra_ahci_host_stop(struct ata_host * host)434ccfde508SMikko Perttunen static void tegra_ahci_host_stop(struct ata_host *host)
435ccfde508SMikko Perttunen {
436ccfde508SMikko Perttunen 	struct ahci_host_priv *hpriv = host->private_data;
437ccfde508SMikko Perttunen 
438ccfde508SMikko Perttunen 	tegra_ahci_controller_deinit(hpriv);
439ccfde508SMikko Perttunen }
440ccfde508SMikko Perttunen 
441ccfde508SMikko Perttunen static struct ata_port_operations ahci_tegra_port_ops = {
442ccfde508SMikko Perttunen 	.inherits	= &ahci_ops,
443ccfde508SMikko Perttunen 	.host_stop	= tegra_ahci_host_stop,
444ccfde508SMikko Perttunen };
445ccfde508SMikko Perttunen 
446ccfde508SMikko Perttunen static const struct ata_port_info ahci_tegra_port_info = {
44701fbf60bSPreetham Ramchandra 	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
448ccfde508SMikko Perttunen 	.pio_mask	= ATA_PIO4,
449ccfde508SMikko Perttunen 	.udma_mask	= ATA_UDMA6,
450ccfde508SMikko Perttunen 	.port_ops	= &ahci_tegra_port_ops,
451ccfde508SMikko Perttunen };
452ccfde508SMikko Perttunen 
45343ee827bSPreetham Ramchandra static const char *const tegra124_supply_names[] = {
45443ee827bSPreetham Ramchandra 	"avdd", "hvdd", "vddio", "target-5v", "target-12v"
45543ee827bSPreetham Ramchandra };
45643ee827bSPreetham Ramchandra 
45756337b55SPreetham Ramchandra static const struct tegra_ahci_ops tegra124_ahci_ops = {
45856337b55SPreetham Ramchandra 	.init = tegra124_ahci_init,
45956337b55SPreetham Ramchandra };
46056337b55SPreetham Ramchandra 
461868ed731SSowjanya Komatineni static const struct tegra_ahci_regs tegra124_ahci_regs = {
462868ed731SSowjanya Komatineni 	.nvoob_comma_cnt_mask = GENMASK(30, 28),
463868ed731SSowjanya Komatineni 	.nvoob_comma_cnt_val = (7 << 28),
464868ed731SSowjanya Komatineni };
465868ed731SSowjanya Komatineni 
46656337b55SPreetham Ramchandra static const struct tegra_ahci_soc tegra124_ahci_soc = {
46743ee827bSPreetham Ramchandra 	.supply_names = tegra124_supply_names,
46843ee827bSPreetham Ramchandra 	.num_supplies = ARRAY_SIZE(tegra124_supply_names),
469502717ccSPreetham Ramchandra 	.supports_devslp = false,
470868ed731SSowjanya Komatineni 	.has_sata_oob_rst = true,
47156337b55SPreetham Ramchandra 	.ops = &tegra124_ahci_ops,
472868ed731SSowjanya Komatineni 	.regs = &tegra124_ahci_regs,
47356337b55SPreetham Ramchandra };
47456337b55SPreetham Ramchandra 
475294840feSPreetham Ramchandra static const struct tegra_ahci_soc tegra210_ahci_soc = {
476294840feSPreetham Ramchandra 	.supports_devslp = false,
477868ed731SSowjanya Komatineni 	.has_sata_oob_rst = true,
478868ed731SSowjanya Komatineni 	.regs = &tegra124_ahci_regs,
479868ed731SSowjanya Komatineni };
480868ed731SSowjanya Komatineni 
481868ed731SSowjanya Komatineni static const struct tegra_ahci_regs tegra186_ahci_regs = {
482868ed731SSowjanya Komatineni 	.nvoob_comma_cnt_mask = GENMASK(23, 16),
483868ed731SSowjanya Komatineni 	.nvoob_comma_cnt_val = (7 << 16),
484868ed731SSowjanya Komatineni };
485868ed731SSowjanya Komatineni 
486868ed731SSowjanya Komatineni static const struct tegra_ahci_soc tegra186_ahci_soc = {
487868ed731SSowjanya Komatineni 	.supports_devslp = false,
488868ed731SSowjanya Komatineni 	.has_sata_oob_rst = false,
489868ed731SSowjanya Komatineni 	.regs = &tegra186_ahci_regs,
490294840feSPreetham Ramchandra };
491294840feSPreetham Ramchandra 
492ccfde508SMikko Perttunen static const struct of_device_id tegra_ahci_of_match[] = {
49356337b55SPreetham Ramchandra 	{
49456337b55SPreetham Ramchandra 		.compatible = "nvidia,tegra124-ahci",
49556337b55SPreetham Ramchandra 		.data = &tegra124_ahci_soc
49656337b55SPreetham Ramchandra 	},
497294840feSPreetham Ramchandra 	{
498294840feSPreetham Ramchandra 		.compatible = "nvidia,tegra210-ahci",
499294840feSPreetham Ramchandra 		.data = &tegra210_ahci_soc
500294840feSPreetham Ramchandra 	},
501868ed731SSowjanya Komatineni 	{
502868ed731SSowjanya Komatineni 		.compatible = "nvidia,tegra186-ahci",
503868ed731SSowjanya Komatineni 		.data = &tegra186_ahci_soc
504868ed731SSowjanya Komatineni 	},
505ccfde508SMikko Perttunen 	{}
506ccfde508SMikko Perttunen };
507ccfde508SMikko Perttunen MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
508ccfde508SMikko Perttunen 
50925df73d9SBart Van Assche static const struct scsi_host_template ahci_platform_sht = {
510018d5ef2SAkinobu Mita 	AHCI_SHT(DRV_NAME),
511018d5ef2SAkinobu Mita };
512018d5ef2SAkinobu Mita 
tegra_ahci_probe(struct platform_device * pdev)513ccfde508SMikko Perttunen static int tegra_ahci_probe(struct platform_device *pdev)
514ccfde508SMikko Perttunen {
515ccfde508SMikko Perttunen 	struct ahci_host_priv *hpriv;
516ccfde508SMikko Perttunen 	struct tegra_ahci_priv *tegra;
517ccfde508SMikko Perttunen 	struct resource *res;
518ccfde508SMikko Perttunen 	int ret;
519ccfde508SMikko Perttunen 
52016af2d65SKunihiko Hayashi 	hpriv = ahci_platform_get_resources(pdev, 0);
521ccfde508SMikko Perttunen 	if (IS_ERR(hpriv))
522ccfde508SMikko Perttunen 		return PTR_ERR(hpriv);
523ccfde508SMikko Perttunen 
524ccfde508SMikko Perttunen 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
525ccfde508SMikko Perttunen 	if (!tegra)
526ccfde508SMikko Perttunen 		return -ENOMEM;
527ccfde508SMikko Perttunen 
528ccfde508SMikko Perttunen 	hpriv->plat_data = tegra;
529ccfde508SMikko Perttunen 
530ccfde508SMikko Perttunen 	tegra->pdev = pdev;
53156337b55SPreetham Ramchandra 	tegra->soc = of_device_get_match_data(&pdev->dev);
532ccfde508SMikko Perttunen 
533*7f187e74SYangtao Li 	tegra->sata_regs = devm_platform_ioremap_resource(pdev, 1);
534ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_regs))
535ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_regs);
536ccfde508SMikko Perttunen 
537502717ccSPreetham Ramchandra 	/*
538502717ccSPreetham Ramchandra 	 * AUX registers is optional.
539502717ccSPreetham Ramchandra 	 */
540502717ccSPreetham Ramchandra 	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
541502717ccSPreetham Ramchandra 	if (res) {
542502717ccSPreetham Ramchandra 		tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res);
543502717ccSPreetham Ramchandra 		if (IS_ERR(tegra->sata_aux_regs))
544502717ccSPreetham Ramchandra 			return PTR_ERR(tegra->sata_aux_regs);
545502717ccSPreetham Ramchandra 	}
546502717ccSPreetham Ramchandra 
547ccfde508SMikko Perttunen 	tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
548ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_rst)) {
549ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get sata reset\n");
550ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_rst);
551ccfde508SMikko Perttunen 	}
552ccfde508SMikko Perttunen 
553868ed731SSowjanya Komatineni 	if (tegra->soc->has_sata_oob_rst) {
554868ed731SSowjanya Komatineni 		tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev,
555868ed731SSowjanya Komatineni 							     "sata-oob");
556ccfde508SMikko Perttunen 		if (IS_ERR(tegra->sata_oob_rst)) {
557ccfde508SMikko Perttunen 			dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
558ccfde508SMikko Perttunen 			return PTR_ERR(tegra->sata_oob_rst);
559ccfde508SMikko Perttunen 		}
560868ed731SSowjanya Komatineni 	}
561ccfde508SMikko Perttunen 
562ccfde508SMikko Perttunen 	tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
563ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_cold_rst)) {
564ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get sata-cold reset\n");
565ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_cold_rst);
566ccfde508SMikko Perttunen 	}
567ccfde508SMikko Perttunen 
568ccfde508SMikko Perttunen 	tegra->sata_clk = devm_clk_get(&pdev->dev, "sata");
569ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_clk)) {
570ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get sata clock\n");
571ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_clk);
572ccfde508SMikko Perttunen 	}
573ccfde508SMikko Perttunen 
57443ee827bSPreetham Ramchandra 	tegra->supplies = devm_kcalloc(&pdev->dev,
57543ee827bSPreetham Ramchandra 				       tegra->soc->num_supplies,
57643ee827bSPreetham Ramchandra 				       sizeof(*tegra->supplies), GFP_KERNEL);
57743ee827bSPreetham Ramchandra 	if (!tegra->supplies)
57843ee827bSPreetham Ramchandra 		return -ENOMEM;
579ccfde508SMikko Perttunen 
580e964a17dSBartosz Golaszewski 	regulator_bulk_set_supply_names(tegra->supplies,
581e964a17dSBartosz Golaszewski 					tegra->soc->supply_names,
582e964a17dSBartosz Golaszewski 					tegra->soc->num_supplies);
58343ee827bSPreetham Ramchandra 
58443ee827bSPreetham Ramchandra 	ret = devm_regulator_bulk_get(&pdev->dev,
58543ee827bSPreetham Ramchandra 				      tegra->soc->num_supplies,
586ccfde508SMikko Perttunen 				      tegra->supplies);
587ccfde508SMikko Perttunen 	if (ret) {
588ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get regulators\n");
589ccfde508SMikko Perttunen 		return ret;
590ccfde508SMikko Perttunen 	}
591ccfde508SMikko Perttunen 
592ccfde508SMikko Perttunen 	ret = tegra_ahci_controller_init(hpriv);
593ccfde508SMikko Perttunen 	if (ret)
594ccfde508SMikko Perttunen 		return ret;
595ccfde508SMikko Perttunen 
596018d5ef2SAkinobu Mita 	ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
597018d5ef2SAkinobu Mita 				      &ahci_platform_sht);
598ccfde508SMikko Perttunen 	if (ret)
599ccfde508SMikko Perttunen 		goto deinit_controller;
600ccfde508SMikko Perttunen 
601ccfde508SMikko Perttunen 	return 0;
602ccfde508SMikko Perttunen 
603ccfde508SMikko Perttunen deinit_controller:
604ccfde508SMikko Perttunen 	tegra_ahci_controller_deinit(hpriv);
605ccfde508SMikko Perttunen 
606ccfde508SMikko Perttunen 	return ret;
607ccfde508SMikko Perttunen };
608ccfde508SMikko Perttunen 
609ccfde508SMikko Perttunen static struct platform_driver tegra_ahci_driver = {
610ccfde508SMikko Perttunen 	.probe = tegra_ahci_probe,
611a7eb54d4SUwe Kleine-König 	.remove_new = ata_platform_remove_one,
612ccfde508SMikko Perttunen 	.driver = {
613018d5ef2SAkinobu Mita 		.name = DRV_NAME,
614ccfde508SMikko Perttunen 		.of_match_table = tegra_ahci_of_match,
615ccfde508SMikko Perttunen 	},
616ccfde508SMikko Perttunen 	/* LP0 suspend support not implemented */
617ccfde508SMikko Perttunen };
618ccfde508SMikko Perttunen module_platform_driver(tegra_ahci_driver);
619ccfde508SMikko Perttunen 
620ccfde508SMikko Perttunen MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
621294840feSPreetham Ramchandra MODULE_DESCRIPTION("Tegra AHCI SATA driver");
622ccfde508SMikko Perttunen MODULE_LICENSE("GPL v2");
623