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