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