xref: /openbmc/linux/drivers/ata/ahci_tegra.c (revision 16af2d65)
1ccfde508SMikko Perttunen /*
2ccfde508SMikko Perttunen  * drivers/ata/ahci_tegra.c
3ccfde508SMikko Perttunen  *
4ccfde508SMikko Perttunen  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
5ccfde508SMikko Perttunen  *
6ccfde508SMikko Perttunen  * Author:
7ccfde508SMikko Perttunen  *	Mikko Perttunen <mperttunen@nvidia.com>
8ccfde508SMikko Perttunen  *
9ccfde508SMikko Perttunen  * This software is licensed under the terms of the GNU General Public
10ccfde508SMikko Perttunen  * License version 2, as published by the Free Software Foundation, and
11ccfde508SMikko Perttunen  * may be copied, distributed, and modified under those terms.
12ccfde508SMikko Perttunen  *
13ccfde508SMikko Perttunen  * This program is distributed in the hope that it will be useful,
14ccfde508SMikko Perttunen  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15ccfde508SMikko Perttunen  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ccfde508SMikko Perttunen  * GNU General Public License for more details.
17ccfde508SMikko Perttunen  *
18ccfde508SMikko Perttunen  */
19ccfde508SMikko Perttunen 
20ccfde508SMikko Perttunen #include <linux/ahci_platform.h>
21ccfde508SMikko Perttunen #include <linux/errno.h>
22ccfde508SMikko Perttunen #include <linux/kernel.h>
23ccfde508SMikko Perttunen #include <linux/module.h>
24ccfde508SMikko Perttunen #include <linux/of_device.h>
25ccfde508SMikko Perttunen #include <linux/platform_device.h>
26ccfde508SMikko Perttunen #include <linux/regulator/consumer.h>
27e327f115SMikko Perttunen #include <linux/reset.h>
28e327f115SMikko Perttunen 
29e327f115SMikko Perttunen #include <soc/tegra/fuse.h>
300e574077SMikko Perttunen #include <soc/tegra/pmc.h>
31e327f115SMikko Perttunen 
32ccfde508SMikko Perttunen #include "ahci.h"
33ccfde508SMikko Perttunen 
34018d5ef2SAkinobu Mita #define DRV_NAME "tegra-ahci"
35018d5ef2SAkinobu Mita 
36ccfde508SMikko Perttunen #define SATA_CONFIGURATION_0				0x180
3756337b55SPreetham Ramchandra #define SATA_CONFIGURATION_0_EN_FPCI			BIT(0)
3856337b55SPreetham Ramchandra #define SATA_CONFIGURATION_0_CLK_OVERRIDE			BIT(31)
39ccfde508SMikko Perttunen 
40ccfde508SMikko Perttunen #define SCFG_OFFSET					0x1000
41ccfde508SMikko Perttunen 
42ccfde508SMikko Perttunen #define T_SATA0_CFG_1					0x04
43ccfde508SMikko Perttunen #define T_SATA0_CFG_1_IO_SPACE				BIT(0)
44ccfde508SMikko Perttunen #define T_SATA0_CFG_1_MEMORY_SPACE			BIT(1)
45ccfde508SMikko Perttunen #define T_SATA0_CFG_1_BUS_MASTER			BIT(2)
46ccfde508SMikko Perttunen #define T_SATA0_CFG_1_SERR				BIT(8)
47ccfde508SMikko Perttunen 
48ccfde508SMikko Perttunen #define T_SATA0_CFG_9					0x24
4956337b55SPreetham Ramchandra #define T_SATA0_CFG_9_BASE_ADDRESS			0x40020000
50ccfde508SMikko Perttunen 
51ccfde508SMikko Perttunen #define SATA_FPCI_BAR5					0x94
5256337b55SPreetham Ramchandra #define SATA_FPCI_BAR5_START_MASK			(0xfffffff << 4)
5356337b55SPreetham Ramchandra #define SATA_FPCI_BAR5_START				(0x0040020 << 4)
5456337b55SPreetham Ramchandra #define SATA_FPCI_BAR5_ACCESS_TYPE			(0x1)
55ccfde508SMikko Perttunen 
56ccfde508SMikko Perttunen #define SATA_INTR_MASK					0x188
57ccfde508SMikko Perttunen #define SATA_INTR_MASK_IP_INT_MASK			BIT(16)
58ccfde508SMikko Perttunen 
5956337b55SPreetham Ramchandra #define T_SATA0_CFG_35					0x94
6056337b55SPreetham Ramchandra #define T_SATA0_CFG_35_IDP_INDEX_MASK			(0x7ff << 2)
6156337b55SPreetham Ramchandra #define T_SATA0_CFG_35_IDP_INDEX			(0x2a << 2)
6256337b55SPreetham Ramchandra 
6356337b55SPreetham Ramchandra #define T_SATA0_AHCI_IDP1				0x98
6456337b55SPreetham Ramchandra #define T_SATA0_AHCI_IDP1_DATA				(0x400040)
6556337b55SPreetham Ramchandra 
6656337b55SPreetham Ramchandra #define T_SATA0_CFG_PHY_1				0x12c
6756337b55SPreetham Ramchandra #define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN			BIT(23)
6856337b55SPreetham Ramchandra #define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
6956337b55SPreetham Ramchandra 
7056337b55SPreetham Ramchandra #define T_SATA0_NVOOB                                   0x114
7156337b55SPreetham Ramchandra #define T_SATA0_NVOOB_COMMA_CNT_MASK                    (0xff << 16)
7256337b55SPreetham Ramchandra #define T_SATA0_NVOOB_COMMA_CNT                         (0x07 << 16)
7356337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK          (0x3 << 24)
7456337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 24)
7556337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK        (0x3 << 26)
7656337b55SPreetham Ramchandra #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH             (0x3 << 26)
7756337b55SPreetham Ramchandra 
7856337b55SPreetham Ramchandra #define T_SATA_CFG_PHY_0                                0x120
7956337b55SPreetham Ramchandra #define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD     BIT(11)
8056337b55SPreetham Ramchandra #define T_SATA_CFG_PHY_0_MASK_SQUELCH                   BIT(24)
8156337b55SPreetham Ramchandra 
8256337b55SPreetham Ramchandra #define T_SATA0_CFG2NVOOB_2				0x134
8356337b55SPreetham Ramchandra #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK	(0x1ff << 18)
8456337b55SPreetham Ramchandra #define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW	(0xc << 18)
8556337b55SPreetham Ramchandra 
86ccfde508SMikko Perttunen #define T_SATA0_AHCI_HBA_CAP_BKDR			0x300
8756337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP	BIT(13)
8856337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP	BIT(14)
8956337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SALP			BIT(26)
9056337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM		BIT(17)
9156337b55SPreetham Ramchandra #define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ			BIT(30)
92ccfde508SMikko Perttunen 
93ccfde508SMikko Perttunen #define T_SATA0_BKDOOR_CC				0x4a4
9456337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK		(0xffff << 16)
9556337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_CLASS_CODE			(0x0106 << 16)
9656337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_PROG_IF_MASK			(0xff << 8)
9756337b55SPreetham Ramchandra #define T_SATA0_BKDOOR_CC_PROG_IF			(0x01 << 8)
98ccfde508SMikko Perttunen 
99ccfde508SMikko Perttunen #define T_SATA0_CFG_SATA				0x54c
100ccfde508SMikko Perttunen #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN		BIT(12)
101ccfde508SMikko Perttunen 
102ccfde508SMikko Perttunen #define T_SATA0_CFG_MISC				0x550
103ccfde508SMikko Perttunen 
104ccfde508SMikko Perttunen #define T_SATA0_INDEX					0x680
105ccfde508SMikko Perttunen 
106ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1			0x690
107ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK		0xff
108ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT		0
109ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK		(0xff << 8)
110ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT	8
111ccfde508SMikko Perttunen 
112ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2			0x694
113ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK		0xff
114ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT		0
115ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK		(0xff << 12)
116ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT	12
117ccfde508SMikko Perttunen 
118ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL2				0x69c
119ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1		0x23
120ccfde508SMikko Perttunen 
121ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL11				0x6d0
122ccfde508SMikko Perttunen #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ		(0x2800 << 16)
123ccfde508SMikko Perttunen 
12456337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL17_0			0x6e8
12556337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1	0x55010000
12656337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL18_0			0x6ec
12756337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2	0x55010000
12856337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL20_0			0x6f4
12956337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1	0x1
13056337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL21_0			0x6f8
13156337b55SPreetham Ramchandra #define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2	0x1
13256337b55SPreetham Ramchandra 
13356337b55SPreetham Ramchandra /* AUX Registers */
13456337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0				0x8
13556337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE		BIT(17)
13656337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT		BIT(13)
13756337b55SPreetham Ramchandra #define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT		BIT(15)
13856337b55SPreetham Ramchandra 
13956337b55SPreetham Ramchandra #define SATA_AUX_RX_STAT_INT_0				0xc
14056337b55SPreetham Ramchandra #define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP		BIT(7)
14156337b55SPreetham Ramchandra 
14256337b55SPreetham Ramchandra #define SATA_AUX_SPARE_CFG0_0				0x18
14356337b55SPreetham Ramchandra #define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID	BIT(14)
14456337b55SPreetham Ramchandra 
145ccfde508SMikko Perttunen #define FUSE_SATA_CALIB					0x124
146ccfde508SMikko Perttunen #define FUSE_SATA_CALIB_MASK				0x3
147ccfde508SMikko Perttunen 
148ccfde508SMikko Perttunen struct sata_pad_calibration {
149ccfde508SMikko Perttunen 	u8 gen1_tx_amp;
150ccfde508SMikko Perttunen 	u8 gen1_tx_peak;
151ccfde508SMikko Perttunen 	u8 gen2_tx_amp;
152ccfde508SMikko Perttunen 	u8 gen2_tx_peak;
153ccfde508SMikko Perttunen };
154ccfde508SMikko Perttunen 
155ccfde508SMikko Perttunen static const struct sata_pad_calibration tegra124_pad_calibration[] = {
156ccfde508SMikko Perttunen 	{0x18, 0x04, 0x18, 0x0a},
157ccfde508SMikko Perttunen 	{0x0e, 0x04, 0x14, 0x0a},
158ccfde508SMikko Perttunen 	{0x0e, 0x07, 0x1a, 0x0e},
159ccfde508SMikko Perttunen 	{0x14, 0x0e, 0x1a, 0x0e},
160ccfde508SMikko Perttunen };
161ccfde508SMikko Perttunen 
16256337b55SPreetham Ramchandra struct tegra_ahci_ops {
16356337b55SPreetham Ramchandra 	int (*init)(struct ahci_host_priv *hpriv);
16456337b55SPreetham Ramchandra };
16556337b55SPreetham Ramchandra 
16656337b55SPreetham Ramchandra struct tegra_ahci_soc {
16743ee827bSPreetham Ramchandra 	const char *const		*supply_names;
16843ee827bSPreetham Ramchandra 	u32				num_supplies;
169502717ccSPreetham Ramchandra 	bool				supports_devslp;
17056337b55SPreetham Ramchandra 	const struct tegra_ahci_ops	*ops;
17156337b55SPreetham Ramchandra };
17256337b55SPreetham Ramchandra 
173ccfde508SMikko Perttunen struct tegra_ahci_priv {
174ccfde508SMikko Perttunen 	struct platform_device	   *pdev;
175ccfde508SMikko Perttunen 	void __iomem		   *sata_regs;
176502717ccSPreetham Ramchandra 	void __iomem		   *sata_aux_regs;
177ccfde508SMikko Perttunen 	struct reset_control	   *sata_rst;
178ccfde508SMikko Perttunen 	struct reset_control	   *sata_oob_rst;
179ccfde508SMikko Perttunen 	struct reset_control	   *sata_cold_rst;
180ccfde508SMikko Perttunen 	/* Needs special handling, cannot use ahci_platform */
181ccfde508SMikko Perttunen 	struct clk		   *sata_clk;
18243ee827bSPreetham Ramchandra 	struct regulator_bulk_data *supplies;
18356337b55SPreetham Ramchandra 	const struct tegra_ahci_soc *soc;
184ccfde508SMikko Perttunen };
185ccfde508SMikko Perttunen 
186502717ccSPreetham Ramchandra static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv)
187502717ccSPreetham Ramchandra {
188502717ccSPreetham Ramchandra 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
189502717ccSPreetham Ramchandra 	u32 val;
190502717ccSPreetham Ramchandra 
191502717ccSPreetham Ramchandra 	if (tegra->sata_aux_regs && !tegra->soc->supports_devslp) {
192502717ccSPreetham Ramchandra 		val = readl(tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
193502717ccSPreetham Ramchandra 		val &= ~SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT;
194502717ccSPreetham Ramchandra 		writel(val, tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
195502717ccSPreetham Ramchandra 	}
196502717ccSPreetham Ramchandra }
197502717ccSPreetham Ramchandra 
19856337b55SPreetham Ramchandra static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
19956337b55SPreetham Ramchandra {
20056337b55SPreetham Ramchandra 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
20156337b55SPreetham Ramchandra 	struct sata_pad_calibration calib;
20256337b55SPreetham Ramchandra 	int ret;
20356337b55SPreetham Ramchandra 	u32 val;
20456337b55SPreetham Ramchandra 
20556337b55SPreetham Ramchandra 	/* Pad calibration */
20656337b55SPreetham Ramchandra 	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
20756337b55SPreetham Ramchandra 	if (ret)
20856337b55SPreetham Ramchandra 		return ret;
20956337b55SPreetham Ramchandra 
21056337b55SPreetham Ramchandra 	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
21156337b55SPreetham Ramchandra 
21256337b55SPreetham Ramchandra 	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
21356337b55SPreetham Ramchandra 
21456337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs +
21556337b55SPreetham Ramchandra 		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
21656337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
21756337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
21856337b55SPreetham Ramchandra 	val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
21956337b55SPreetham Ramchandra 	val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
22056337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET +
22156337b55SPreetham Ramchandra 	       T_SATA0_CHX_PHY_CTRL1_GEN1);
22256337b55SPreetham Ramchandra 
22356337b55SPreetham Ramchandra 	val = readl(tegra->sata_regs +
22456337b55SPreetham Ramchandra 		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
22556337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
22656337b55SPreetham Ramchandra 	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
22756337b55SPreetham Ramchandra 	val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
22856337b55SPreetham Ramchandra 	val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
22956337b55SPreetham Ramchandra 	writel(val, tegra->sata_regs + SCFG_OFFSET +
23056337b55SPreetham Ramchandra 	       T_SATA0_CHX_PHY_CTRL1_GEN2);
23156337b55SPreetham Ramchandra 
23256337b55SPreetham Ramchandra 	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
23356337b55SPreetham Ramchandra 	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
23456337b55SPreetham Ramchandra 	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
23556337b55SPreetham Ramchandra 	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
23656337b55SPreetham Ramchandra 
23756337b55SPreetham Ramchandra 	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
23856337b55SPreetham Ramchandra 
23956337b55SPreetham Ramchandra 	return 0;
24056337b55SPreetham Ramchandra }
24156337b55SPreetham Ramchandra 
242ccfde508SMikko Perttunen static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
243ccfde508SMikko Perttunen {
244ccfde508SMikko Perttunen 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
245ccfde508SMikko Perttunen 	int ret;
246ccfde508SMikko Perttunen 
24743ee827bSPreetham Ramchandra 	ret = regulator_bulk_enable(tegra->soc->num_supplies,
248ccfde508SMikko Perttunen 				    tegra->supplies);
249ccfde508SMikko Perttunen 	if (ret)
250ccfde508SMikko Perttunen 		return ret;
251ccfde508SMikko Perttunen 
252ccfde508SMikko Perttunen 	ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
253ccfde508SMikko Perttunen 						tegra->sata_clk,
254ccfde508SMikko Perttunen 						tegra->sata_rst);
255ccfde508SMikko Perttunen 	if (ret)
256ccfde508SMikko Perttunen 		goto disable_regulators;
257ccfde508SMikko Perttunen 
258ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_oob_rst);
259ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_cold_rst);
260ccfde508SMikko Perttunen 
261ccfde508SMikko Perttunen 	ret = ahci_platform_enable_resources(hpriv);
262ccfde508SMikko Perttunen 	if (ret)
263ccfde508SMikko Perttunen 		goto disable_power;
264ccfde508SMikko Perttunen 
265ccfde508SMikko Perttunen 	reset_control_deassert(tegra->sata_cold_rst);
266ccfde508SMikko Perttunen 	reset_control_deassert(tegra->sata_oob_rst);
267ccfde508SMikko Perttunen 
268ccfde508SMikko Perttunen 	return 0;
269ccfde508SMikko Perttunen 
270ccfde508SMikko Perttunen disable_power:
271ccfde508SMikko Perttunen 	clk_disable_unprepare(tegra->sata_clk);
272ccfde508SMikko Perttunen 
273ccfde508SMikko Perttunen 	tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
274ccfde508SMikko Perttunen 
275ccfde508SMikko Perttunen disable_regulators:
27643ee827bSPreetham Ramchandra 	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
277ccfde508SMikko Perttunen 
278ccfde508SMikko Perttunen 	return ret;
279ccfde508SMikko Perttunen }
280ccfde508SMikko Perttunen 
281ccfde508SMikko Perttunen static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
282ccfde508SMikko Perttunen {
283ccfde508SMikko Perttunen 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
284ccfde508SMikko Perttunen 
285ccfde508SMikko Perttunen 	ahci_platform_disable_resources(hpriv);
286ccfde508SMikko Perttunen 
287ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_rst);
288ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_oob_rst);
289ccfde508SMikko Perttunen 	reset_control_assert(tegra->sata_cold_rst);
290ccfde508SMikko Perttunen 
291ccfde508SMikko Perttunen 	clk_disable_unprepare(tegra->sata_clk);
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 
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);
34256337b55SPreetham Ramchandra 	val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK |
34356337b55SPreetham Ramchandra 		 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
34456337b55SPreetham Ramchandra 		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
34556337b55SPreetham Ramchandra 	val |= (T_SATA0_NVOOB_COMMA_CNT |
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 
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 
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 
46156337b55SPreetham Ramchandra static const struct tegra_ahci_soc tegra124_ahci_soc = {
46243ee827bSPreetham Ramchandra 	.supply_names = tegra124_supply_names,
46343ee827bSPreetham Ramchandra 	.num_supplies = ARRAY_SIZE(tegra124_supply_names),
464502717ccSPreetham Ramchandra 	.supports_devslp = false,
46556337b55SPreetham Ramchandra 	.ops = &tegra124_ahci_ops,
46656337b55SPreetham Ramchandra };
46756337b55SPreetham Ramchandra 
468294840feSPreetham Ramchandra static const struct tegra_ahci_soc tegra210_ahci_soc = {
469294840feSPreetham Ramchandra 	.supports_devslp = false,
470294840feSPreetham Ramchandra };
471294840feSPreetham Ramchandra 
472ccfde508SMikko Perttunen static const struct of_device_id tegra_ahci_of_match[] = {
47356337b55SPreetham Ramchandra 	{
47456337b55SPreetham Ramchandra 		.compatible = "nvidia,tegra124-ahci",
47556337b55SPreetham Ramchandra 		.data = &tegra124_ahci_soc
47656337b55SPreetham Ramchandra 	},
477294840feSPreetham Ramchandra 	{
478294840feSPreetham Ramchandra 		.compatible = "nvidia,tegra210-ahci",
479294840feSPreetham Ramchandra 		.data = &tegra210_ahci_soc
480294840feSPreetham Ramchandra 	},
481ccfde508SMikko Perttunen 	{}
482ccfde508SMikko Perttunen };
483ccfde508SMikko Perttunen MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
484ccfde508SMikko Perttunen 
485018d5ef2SAkinobu Mita static struct scsi_host_template ahci_platform_sht = {
486018d5ef2SAkinobu Mita 	AHCI_SHT(DRV_NAME),
487018d5ef2SAkinobu Mita };
488018d5ef2SAkinobu Mita 
489ccfde508SMikko Perttunen static int tegra_ahci_probe(struct platform_device *pdev)
490ccfde508SMikko Perttunen {
491ccfde508SMikko Perttunen 	struct ahci_host_priv *hpriv;
492ccfde508SMikko Perttunen 	struct tegra_ahci_priv *tegra;
493ccfde508SMikko Perttunen 	struct resource *res;
494ccfde508SMikko Perttunen 	int ret;
49543ee827bSPreetham Ramchandra 	unsigned int i;
496ccfde508SMikko Perttunen 
49716af2d65SKunihiko Hayashi 	hpriv = ahci_platform_get_resources(pdev, 0);
498ccfde508SMikko Perttunen 	if (IS_ERR(hpriv))
499ccfde508SMikko Perttunen 		return PTR_ERR(hpriv);
500ccfde508SMikko Perttunen 
501ccfde508SMikko Perttunen 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
502ccfde508SMikko Perttunen 	if (!tegra)
503ccfde508SMikko Perttunen 		return -ENOMEM;
504ccfde508SMikko Perttunen 
505ccfde508SMikko Perttunen 	hpriv->plat_data = tegra;
506ccfde508SMikko Perttunen 
507ccfde508SMikko Perttunen 	tegra->pdev = pdev;
50856337b55SPreetham Ramchandra 	tegra->soc = of_device_get_match_data(&pdev->dev);
509ccfde508SMikko Perttunen 
510ccfde508SMikko Perttunen 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
511ccfde508SMikko Perttunen 	tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);
512ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_regs))
513ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_regs);
514ccfde508SMikko Perttunen 
515502717ccSPreetham Ramchandra 	/*
516502717ccSPreetham Ramchandra 	 * AUX registers is optional.
517502717ccSPreetham Ramchandra 	 */
518502717ccSPreetham Ramchandra 	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
519502717ccSPreetham Ramchandra 	if (res) {
520502717ccSPreetham Ramchandra 		tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res);
521502717ccSPreetham Ramchandra 		if (IS_ERR(tegra->sata_aux_regs))
522502717ccSPreetham Ramchandra 			return PTR_ERR(tegra->sata_aux_regs);
523502717ccSPreetham Ramchandra 	}
524502717ccSPreetham Ramchandra 
525ccfde508SMikko Perttunen 	tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
526ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_rst)) {
527ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get sata reset\n");
528ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_rst);
529ccfde508SMikko Perttunen 	}
530ccfde508SMikko Perttunen 
531ccfde508SMikko Perttunen 	tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, "sata-oob");
532ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_oob_rst)) {
533ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
534ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_oob_rst);
535ccfde508SMikko Perttunen 	}
536ccfde508SMikko Perttunen 
537ccfde508SMikko Perttunen 	tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
538ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_cold_rst)) {
539ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get sata-cold reset\n");
540ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_cold_rst);
541ccfde508SMikko Perttunen 	}
542ccfde508SMikko Perttunen 
543ccfde508SMikko Perttunen 	tegra->sata_clk = devm_clk_get(&pdev->dev, "sata");
544ccfde508SMikko Perttunen 	if (IS_ERR(tegra->sata_clk)) {
545ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get sata clock\n");
546ccfde508SMikko Perttunen 		return PTR_ERR(tegra->sata_clk);
547ccfde508SMikko Perttunen 	}
548ccfde508SMikko Perttunen 
54943ee827bSPreetham Ramchandra 	tegra->supplies = devm_kcalloc(&pdev->dev,
55043ee827bSPreetham Ramchandra 				       tegra->soc->num_supplies,
55143ee827bSPreetham Ramchandra 				       sizeof(*tegra->supplies), GFP_KERNEL);
55243ee827bSPreetham Ramchandra 	if (!tegra->supplies)
55343ee827bSPreetham Ramchandra 		return -ENOMEM;
554ccfde508SMikko Perttunen 
55543ee827bSPreetham Ramchandra 	for (i = 0; i < tegra->soc->num_supplies; i++)
55643ee827bSPreetham Ramchandra 		tegra->supplies[i].supply = tegra->soc->supply_names[i];
55743ee827bSPreetham Ramchandra 
55843ee827bSPreetham Ramchandra 	ret = devm_regulator_bulk_get(&pdev->dev,
55943ee827bSPreetham Ramchandra 				      tegra->soc->num_supplies,
560ccfde508SMikko Perttunen 				      tegra->supplies);
561ccfde508SMikko Perttunen 	if (ret) {
562ccfde508SMikko Perttunen 		dev_err(&pdev->dev, "Failed to get regulators\n");
563ccfde508SMikko Perttunen 		return ret;
564ccfde508SMikko Perttunen 	}
565ccfde508SMikko Perttunen 
566ccfde508SMikko Perttunen 	ret = tegra_ahci_controller_init(hpriv);
567ccfde508SMikko Perttunen 	if (ret)
568ccfde508SMikko Perttunen 		return ret;
569ccfde508SMikko Perttunen 
570018d5ef2SAkinobu Mita 	ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
571018d5ef2SAkinobu Mita 				      &ahci_platform_sht);
572ccfde508SMikko Perttunen 	if (ret)
573ccfde508SMikko Perttunen 		goto deinit_controller;
574ccfde508SMikko Perttunen 
575ccfde508SMikko Perttunen 	return 0;
576ccfde508SMikko Perttunen 
577ccfde508SMikko Perttunen deinit_controller:
578ccfde508SMikko Perttunen 	tegra_ahci_controller_deinit(hpriv);
579ccfde508SMikko Perttunen 
580ccfde508SMikko Perttunen 	return ret;
581ccfde508SMikko Perttunen };
582ccfde508SMikko Perttunen 
583ccfde508SMikko Perttunen static struct platform_driver tegra_ahci_driver = {
584ccfde508SMikko Perttunen 	.probe = tegra_ahci_probe,
585ccfde508SMikko Perttunen 	.remove = ata_platform_remove_one,
586ccfde508SMikko Perttunen 	.driver = {
587018d5ef2SAkinobu Mita 		.name = DRV_NAME,
588ccfde508SMikko Perttunen 		.of_match_table = tegra_ahci_of_match,
589ccfde508SMikko Perttunen 	},
590ccfde508SMikko Perttunen 	/* LP0 suspend support not implemented */
591ccfde508SMikko Perttunen };
592ccfde508SMikko Perttunen module_platform_driver(tegra_ahci_driver);
593ccfde508SMikko Perttunen 
594ccfde508SMikko Perttunen MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
595294840feSPreetham Ramchandra MODULE_DESCRIPTION("Tegra AHCI SATA driver");
596ccfde508SMikko Perttunen MODULE_LICENSE("GPL v2");
597