cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ahci_tegra.c (18944B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * drivers/ata/ahci_tegra.c
      4 *
      5 * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
      6 *
      7 * Author:
      8 *	Mikko Perttunen <mperttunen@nvidia.com>
      9 */
     10
     11#include <linux/ahci_platform.h>
     12#include <linux/errno.h>
     13#include <linux/kernel.h>
     14#include <linux/module.h>
     15#include <linux/of_device.h>
     16#include <linux/platform_device.h>
     17#include <linux/regulator/consumer.h>
     18#include <linux/reset.h>
     19
     20#include <soc/tegra/fuse.h>
     21#include <soc/tegra/pmc.h>
     22
     23#include "ahci.h"
     24
     25#define DRV_NAME "tegra-ahci"
     26
     27#define SATA_CONFIGURATION_0				0x180
     28#define SATA_CONFIGURATION_0_EN_FPCI			BIT(0)
     29#define SATA_CONFIGURATION_0_CLK_OVERRIDE			BIT(31)
     30
     31#define SCFG_OFFSET					0x1000
     32
     33#define T_SATA0_CFG_1					0x04
     34#define T_SATA0_CFG_1_IO_SPACE				BIT(0)
     35#define T_SATA0_CFG_1_MEMORY_SPACE			BIT(1)
     36#define T_SATA0_CFG_1_BUS_MASTER			BIT(2)
     37#define T_SATA0_CFG_1_SERR				BIT(8)
     38
     39#define T_SATA0_CFG_9					0x24
     40#define T_SATA0_CFG_9_BASE_ADDRESS			0x40020000
     41
     42#define SATA_FPCI_BAR5					0x94
     43#define SATA_FPCI_BAR5_START_MASK			(0xfffffff << 4)
     44#define SATA_FPCI_BAR5_START				(0x0040020 << 4)
     45#define SATA_FPCI_BAR5_ACCESS_TYPE			(0x1)
     46
     47#define SATA_INTR_MASK					0x188
     48#define SATA_INTR_MASK_IP_INT_MASK			BIT(16)
     49
     50#define T_SATA0_CFG_35					0x94
     51#define T_SATA0_CFG_35_IDP_INDEX_MASK			(0x7ff << 2)
     52#define T_SATA0_CFG_35_IDP_INDEX			(0x2a << 2)
     53
     54#define T_SATA0_AHCI_IDP1				0x98
     55#define T_SATA0_AHCI_IDP1_DATA				(0x400040)
     56
     57#define T_SATA0_CFG_PHY_1				0x12c
     58#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN			BIT(23)
     59#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
     60
     61#define T_SATA0_NVOOB                                   0x114
     62#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK          (0x3 << 24)
     63#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 24)
     64#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK        (0x3 << 26)
     65#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH             (0x3 << 26)
     66
     67#define T_SATA_CFG_PHY_0                                0x120
     68#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD     BIT(11)
     69#define T_SATA_CFG_PHY_0_MASK_SQUELCH                   BIT(24)
     70
     71#define T_SATA0_CFG2NVOOB_2				0x134
     72#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK	(0x1ff << 18)
     73#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW	(0xc << 18)
     74
     75#define T_SATA0_AHCI_HBA_CAP_BKDR			0x300
     76#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP	BIT(13)
     77#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP	BIT(14)
     78#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP			BIT(26)
     79#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM		BIT(17)
     80#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ			BIT(30)
     81
     82#define T_SATA0_BKDOOR_CC				0x4a4
     83#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK		(0xffff << 16)
     84#define T_SATA0_BKDOOR_CC_CLASS_CODE			(0x0106 << 16)
     85#define T_SATA0_BKDOOR_CC_PROG_IF_MASK			(0xff << 8)
     86#define T_SATA0_BKDOOR_CC_PROG_IF			(0x01 << 8)
     87
     88#define T_SATA0_CFG_SATA				0x54c
     89#define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN		BIT(12)
     90
     91#define T_SATA0_CFG_MISC				0x550
     92
     93#define T_SATA0_INDEX					0x680
     94
     95#define T_SATA0_CHX_PHY_CTRL1_GEN1			0x690
     96#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK		0xff
     97#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT		0
     98#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK		(0xff << 8)
     99#define T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT	8
    100
    101#define T_SATA0_CHX_PHY_CTRL1_GEN2			0x694
    102#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK		0xff
    103#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_SHIFT		0
    104#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK		(0xff << 12)
    105#define T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_SHIFT	12
    106
    107#define T_SATA0_CHX_PHY_CTRL2				0x69c
    108#define T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1		0x23
    109
    110#define T_SATA0_CHX_PHY_CTRL11				0x6d0
    111#define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ		(0x2800 << 16)
    112
    113#define T_SATA0_CHX_PHY_CTRL17_0			0x6e8
    114#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1	0x55010000
    115#define T_SATA0_CHX_PHY_CTRL18_0			0x6ec
    116#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2	0x55010000
    117#define T_SATA0_CHX_PHY_CTRL20_0			0x6f4
    118#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1	0x1
    119#define T_SATA0_CHX_PHY_CTRL21_0			0x6f8
    120#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2	0x1
    121
    122/* AUX Registers */
    123#define SATA_AUX_MISC_CNTL_1_0				0x8
    124#define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE		BIT(17)
    125#define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT		BIT(13)
    126#define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT		BIT(15)
    127
    128#define SATA_AUX_RX_STAT_INT_0				0xc
    129#define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP		BIT(7)
    130
    131#define SATA_AUX_SPARE_CFG0_0				0x18
    132#define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID	BIT(14)
    133
    134#define FUSE_SATA_CALIB					0x124
    135#define FUSE_SATA_CALIB_MASK				0x3
    136
    137struct sata_pad_calibration {
    138	u8 gen1_tx_amp;
    139	u8 gen1_tx_peak;
    140	u8 gen2_tx_amp;
    141	u8 gen2_tx_peak;
    142};
    143
    144static const struct sata_pad_calibration tegra124_pad_calibration[] = {
    145	{0x18, 0x04, 0x18, 0x0a},
    146	{0x0e, 0x04, 0x14, 0x0a},
    147	{0x0e, 0x07, 0x1a, 0x0e},
    148	{0x14, 0x0e, 0x1a, 0x0e},
    149};
    150
    151struct tegra_ahci_ops {
    152	int (*init)(struct ahci_host_priv *hpriv);
    153};
    154
    155struct tegra_ahci_regs {
    156	unsigned int nvoob_comma_cnt_mask;
    157	unsigned int nvoob_comma_cnt_val;
    158};
    159
    160struct tegra_ahci_soc {
    161	const char *const		*supply_names;
    162	u32				num_supplies;
    163	bool				supports_devslp;
    164	bool				has_sata_oob_rst;
    165	const struct tegra_ahci_ops	*ops;
    166	const struct tegra_ahci_regs	*regs;
    167};
    168
    169struct tegra_ahci_priv {
    170	struct platform_device	   *pdev;
    171	void __iomem		   *sata_regs;
    172	void __iomem		   *sata_aux_regs;
    173	struct reset_control	   *sata_rst;
    174	struct reset_control	   *sata_oob_rst;
    175	struct reset_control	   *sata_cold_rst;
    176	/* Needs special handling, cannot use ahci_platform */
    177	struct clk		   *sata_clk;
    178	struct regulator_bulk_data *supplies;
    179	const struct tegra_ahci_soc *soc;
    180};
    181
    182static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv)
    183{
    184	struct tegra_ahci_priv *tegra = hpriv->plat_data;
    185	u32 val;
    186
    187	if (tegra->sata_aux_regs && !tegra->soc->supports_devslp) {
    188		val = readl(tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
    189		val &= ~SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT;
    190		writel(val, tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0);
    191	}
    192}
    193
    194static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
    195{
    196	struct tegra_ahci_priv *tegra = hpriv->plat_data;
    197	struct sata_pad_calibration calib;
    198	int ret;
    199	u32 val;
    200
    201	/* Pad calibration */
    202	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
    203	if (ret)
    204		return ret;
    205
    206	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
    207
    208	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
    209
    210	val = readl(tegra->sata_regs +
    211		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
    212	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
    213	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
    214	val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
    215	val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
    216	writel(val, tegra->sata_regs + SCFG_OFFSET +
    217	       T_SATA0_CHX_PHY_CTRL1_GEN1);
    218
    219	val = readl(tegra->sata_regs +
    220		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
    221	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
    222	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
    223	val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
    224	val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
    225	writel(val, tegra->sata_regs + SCFG_OFFSET +
    226	       T_SATA0_CHX_PHY_CTRL1_GEN2);
    227
    228	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
    229	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
    230	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
    231	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
    232
    233	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
    234
    235	return 0;
    236}
    237
    238static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
    239{
    240	struct tegra_ahci_priv *tegra = hpriv->plat_data;
    241	int ret;
    242
    243	ret = regulator_bulk_enable(tegra->soc->num_supplies,
    244				    tegra->supplies);
    245	if (ret)
    246		return ret;
    247
    248	if (!tegra->pdev->dev.pm_domain) {
    249		ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
    250							tegra->sata_clk,
    251							tegra->sata_rst);
    252		if (ret)
    253			goto disable_regulators;
    254	}
    255
    256	reset_control_assert(tegra->sata_oob_rst);
    257	reset_control_assert(tegra->sata_cold_rst);
    258
    259	ret = ahci_platform_enable_resources(hpriv);
    260	if (ret)
    261		goto disable_power;
    262
    263	reset_control_deassert(tegra->sata_cold_rst);
    264	reset_control_deassert(tegra->sata_oob_rst);
    265
    266	return 0;
    267
    268disable_power:
    269	clk_disable_unprepare(tegra->sata_clk);
    270
    271	if (!tegra->pdev->dev.pm_domain)
    272		tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
    273
    274disable_regulators:
    275	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
    276
    277	return ret;
    278}
    279
    280static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
    281{
    282	struct tegra_ahci_priv *tegra = hpriv->plat_data;
    283
    284	ahci_platform_disable_resources(hpriv);
    285
    286	reset_control_assert(tegra->sata_rst);
    287	reset_control_assert(tegra->sata_oob_rst);
    288	reset_control_assert(tegra->sata_cold_rst);
    289
    290	clk_disable_unprepare(tegra->sata_clk);
    291	if (!tegra->pdev->dev.pm_domain)
    292		tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
    293
    294	regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
    295}
    296
    297static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
    298{
    299	struct tegra_ahci_priv *tegra = hpriv->plat_data;
    300	int ret;
    301	u32 val;
    302
    303	ret = tegra_ahci_power_on(hpriv);
    304	if (ret) {
    305		dev_err(&tegra->pdev->dev,
    306			"failed to power on AHCI controller: %d\n", ret);
    307		return ret;
    308	}
    309
    310	/*
    311	 * Program the following SATA IPFS registers to allow SW accesses to
    312	 * SATA's MMIO register range.
    313	 */
    314	val = readl(tegra->sata_regs + SATA_FPCI_BAR5);
    315	val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE);
    316	val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE;
    317	writel(val, tegra->sata_regs + SATA_FPCI_BAR5);
    318
    319	/* Program the following SATA IPFS register to enable the SATA */
    320	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
    321	val |= SATA_CONFIGURATION_0_EN_FPCI;
    322	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
    323
    324	/* Electrical settings for better link stability */
    325	val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1;
    326	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0);
    327	val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2;
    328	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0);
    329	val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1;
    330	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0);
    331	val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2;
    332	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0);
    333
    334	/* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */
    335
    336	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
    337	val |= T_SATA_CFG_PHY_0_MASK_SQUELCH;
    338	val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
    339	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
    340
    341	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
    342	val &= ~(tegra->soc->regs->nvoob_comma_cnt_mask |
    343		 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
    344		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
    345	val |= (tegra->soc->regs->nvoob_comma_cnt_val |
    346		T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
    347		T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
    348	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
    349
    350	/*
    351	 * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns
    352	 */
    353	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
    354	val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
    355	val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
    356	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
    357
    358	if (tegra->soc->ops && tegra->soc->ops->init)
    359		tegra->soc->ops->init(hpriv);
    360
    361	/*
    362	 * Program the following SATA configuration registers to
    363	 * initialize SATA
    364	 */
    365	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
    366	val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
    367		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR);
    368	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
    369	val = T_SATA0_CFG_9_BASE_ADDRESS;
    370	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
    371
    372	/* Program Class Code and Programming interface for SATA */
    373	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
    374	val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
    375	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
    376
    377	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
    378	val &=
    379	    ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK |
    380	      T_SATA0_BKDOOR_CC_PROG_IF_MASK);
    381	val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF;
    382	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
    383
    384	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
    385	val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
    386	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
    387
    388	/* Enabling LPM capabilities through Backdoor Programming */
    389	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
    390	val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP |
    391		T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP |
    392		T_SATA0_AHCI_HBA_CAP_BKDR_SALP |
    393		T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM);
    394	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
    395
    396	/* SATA Second Level Clock Gating configuration
    397	 * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane
    398	 * IDDQ Signals
    399	 */
    400	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
    401	val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK;
    402	val |= T_SATA0_CFG_35_IDP_INDEX;
    403	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
    404
    405	val = T_SATA0_AHCI_IDP1_DATA;
    406	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1);
    407
    408	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
    409	val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN |
    410		T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN);
    411	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
    412
    413	/* Enabling IPFS Clock Gating */
    414	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
    415	val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE;
    416	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
    417
    418	tegra_ahci_handle_quirks(hpriv);
    419
    420	/* Unmask SATA interrupts */
    421
    422	val = readl(tegra->sata_regs + SATA_INTR_MASK);
    423	val |= SATA_INTR_MASK_IP_INT_MASK;
    424	writel(val, tegra->sata_regs + SATA_INTR_MASK);
    425
    426	return 0;
    427}
    428
    429static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
    430{
    431	tegra_ahci_power_off(hpriv);
    432}
    433
    434static void tegra_ahci_host_stop(struct ata_host *host)
    435{
    436	struct ahci_host_priv *hpriv = host->private_data;
    437
    438	tegra_ahci_controller_deinit(hpriv);
    439}
    440
    441static struct ata_port_operations ahci_tegra_port_ops = {
    442	.inherits	= &ahci_ops,
    443	.host_stop	= tegra_ahci_host_stop,
    444};
    445
    446static const struct ata_port_info ahci_tegra_port_info = {
    447	.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
    448	.pio_mask	= ATA_PIO4,
    449	.udma_mask	= ATA_UDMA6,
    450	.port_ops	= &ahci_tegra_port_ops,
    451};
    452
    453static const char *const tegra124_supply_names[] = {
    454	"avdd", "hvdd", "vddio", "target-5v", "target-12v"
    455};
    456
    457static const struct tegra_ahci_ops tegra124_ahci_ops = {
    458	.init = tegra124_ahci_init,
    459};
    460
    461static const struct tegra_ahci_regs tegra124_ahci_regs = {
    462	.nvoob_comma_cnt_mask = GENMASK(30, 28),
    463	.nvoob_comma_cnt_val = (7 << 28),
    464};
    465
    466static const struct tegra_ahci_soc tegra124_ahci_soc = {
    467	.supply_names = tegra124_supply_names,
    468	.num_supplies = ARRAY_SIZE(tegra124_supply_names),
    469	.supports_devslp = false,
    470	.has_sata_oob_rst = true,
    471	.ops = &tegra124_ahci_ops,
    472	.regs = &tegra124_ahci_regs,
    473};
    474
    475static const struct tegra_ahci_soc tegra210_ahci_soc = {
    476	.supports_devslp = false,
    477	.has_sata_oob_rst = true,
    478	.regs = &tegra124_ahci_regs,
    479};
    480
    481static const struct tegra_ahci_regs tegra186_ahci_regs = {
    482	.nvoob_comma_cnt_mask = GENMASK(23, 16),
    483	.nvoob_comma_cnt_val = (7 << 16),
    484};
    485
    486static const struct tegra_ahci_soc tegra186_ahci_soc = {
    487	.supports_devslp = false,
    488	.has_sata_oob_rst = false,
    489	.regs = &tegra186_ahci_regs,
    490};
    491
    492static const struct of_device_id tegra_ahci_of_match[] = {
    493	{
    494		.compatible = "nvidia,tegra124-ahci",
    495		.data = &tegra124_ahci_soc
    496	},
    497	{
    498		.compatible = "nvidia,tegra210-ahci",
    499		.data = &tegra210_ahci_soc
    500	},
    501	{
    502		.compatible = "nvidia,tegra186-ahci",
    503		.data = &tegra186_ahci_soc
    504	},
    505	{}
    506};
    507MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
    508
    509static struct scsi_host_template ahci_platform_sht = {
    510	AHCI_SHT(DRV_NAME),
    511};
    512
    513static int tegra_ahci_probe(struct platform_device *pdev)
    514{
    515	struct ahci_host_priv *hpriv;
    516	struct tegra_ahci_priv *tegra;
    517	struct resource *res;
    518	int ret;
    519
    520	hpriv = ahci_platform_get_resources(pdev, 0);
    521	if (IS_ERR(hpriv))
    522		return PTR_ERR(hpriv);
    523
    524	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
    525	if (!tegra)
    526		return -ENOMEM;
    527
    528	hpriv->plat_data = tegra;
    529
    530	tegra->pdev = pdev;
    531	tegra->soc = of_device_get_match_data(&pdev->dev);
    532
    533	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
    534	tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);
    535	if (IS_ERR(tegra->sata_regs))
    536		return PTR_ERR(tegra->sata_regs);
    537
    538	/*
    539	 * AUX registers is optional.
    540	 */
    541	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
    542	if (res) {
    543		tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res);
    544		if (IS_ERR(tegra->sata_aux_regs))
    545			return PTR_ERR(tegra->sata_aux_regs);
    546	}
    547
    548	tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata");
    549	if (IS_ERR(tegra->sata_rst)) {
    550		dev_err(&pdev->dev, "Failed to get sata reset\n");
    551		return PTR_ERR(tegra->sata_rst);
    552	}
    553
    554	if (tegra->soc->has_sata_oob_rst) {
    555		tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev,
    556							     "sata-oob");
    557		if (IS_ERR(tegra->sata_oob_rst)) {
    558			dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
    559			return PTR_ERR(tegra->sata_oob_rst);
    560		}
    561	}
    562
    563	tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
    564	if (IS_ERR(tegra->sata_cold_rst)) {
    565		dev_err(&pdev->dev, "Failed to get sata-cold reset\n");
    566		return PTR_ERR(tegra->sata_cold_rst);
    567	}
    568
    569	tegra->sata_clk = devm_clk_get(&pdev->dev, "sata");
    570	if (IS_ERR(tegra->sata_clk)) {
    571		dev_err(&pdev->dev, "Failed to get sata clock\n");
    572		return PTR_ERR(tegra->sata_clk);
    573	}
    574
    575	tegra->supplies = devm_kcalloc(&pdev->dev,
    576				       tegra->soc->num_supplies,
    577				       sizeof(*tegra->supplies), GFP_KERNEL);
    578	if (!tegra->supplies)
    579		return -ENOMEM;
    580
    581	regulator_bulk_set_supply_names(tegra->supplies,
    582					tegra->soc->supply_names,
    583					tegra->soc->num_supplies);
    584
    585	ret = devm_regulator_bulk_get(&pdev->dev,
    586				      tegra->soc->num_supplies,
    587				      tegra->supplies);
    588	if (ret) {
    589		dev_err(&pdev->dev, "Failed to get regulators\n");
    590		return ret;
    591	}
    592
    593	ret = tegra_ahci_controller_init(hpriv);
    594	if (ret)
    595		return ret;
    596
    597	ret = ahci_platform_init_host(pdev, hpriv, &ahci_tegra_port_info,
    598				      &ahci_platform_sht);
    599	if (ret)
    600		goto deinit_controller;
    601
    602	return 0;
    603
    604deinit_controller:
    605	tegra_ahci_controller_deinit(hpriv);
    606
    607	return ret;
    608};
    609
    610static struct platform_driver tegra_ahci_driver = {
    611	.probe = tegra_ahci_probe,
    612	.remove = ata_platform_remove_one,
    613	.driver = {
    614		.name = DRV_NAME,
    615		.of_match_table = tegra_ahci_of_match,
    616	},
    617	/* LP0 suspend support not implemented */
    618};
    619module_platform_driver(tegra_ahci_driver);
    620
    621MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
    622MODULE_DESCRIPTION("Tegra AHCI SATA driver");
    623MODULE_LICENSE("GPL v2");