diff mbox series

[V6,3/7] ata: ahci_tegra: Update initialization sequence

Message ID 1515482234-24716-4-git-send-email-pchandru@nvidia.com
State Not Applicable
Delegated to: David Miller
Headers show
Series Refactor and add AHCI support for tegra210 | expand

Commit Message

Preetham Chandru Ramchandra Jan. 9, 2018, 7:17 a.m. UTC
From: Preetham Ramchandra <pchandru@nvidia.com>

Update the controller initialization sequence and move
t124 specifics to tegra124_ahci_init.

Signed-off-by: Preetham Chandru R <pchandru@nvidia.com>
---
 drivers/ata/ahci_tegra.c | 289 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 224 insertions(+), 65 deletions(-)

Comments

Mikko Perttunen Jan. 23, 2018, 3:44 p.m. UTC | #1
On 01/09/2018 09:17 AM, Preetham Chandru Ramchandra wrote:
> From: Preetham Ramchandra <pchandru@nvidia.com>
> 
> Update the controller initialization sequence and move
> t124 specifics to tegra124_ahci_init.
> 
> Signed-off-by: Preetham Chandru R <pchandru@nvidia.com>
> ---
>   drivers/ata/ahci_tegra.c | 289 ++++++++++++++++++++++++++++++++++++-----------
>   1 file changed, 224 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
> index 3a62eb246d80..71850e96e787 100644
> --- a/drivers/ata/ahci_tegra.c
> +++ b/drivers/ata/ahci_tegra.c
> @@ -34,7 +34,8 @@
>   #define DRV_NAME "tegra-ahci"
>   
>   #define SATA_CONFIGURATION_0				0x180
> -#define SATA_CONFIGURATION_EN_FPCI			BIT(0)
> +#define SATA_CONFIGURATION_0_EN_FPCI			BIT(0)
> +#define SATA_CONFIGURATION_0_CLK_OVERRIDE			BIT(31)
>   
>   #define SCFG_OFFSET					0x1000
>   
> @@ -45,17 +46,55 @@
>   #define T_SATA0_CFG_1_SERR				BIT(8)
>   
>   #define T_SATA0_CFG_9					0x24
> -#define T_SATA0_CFG_9_BASE_ADDRESS_SHIFT		13
> +#define T_SATA0_CFG_9_BASE_ADDRESS			0x40020000
>   
>   #define SATA_FPCI_BAR5					0x94
> -#define SATA_FPCI_BAR5_START_SHIFT			4
> +#define SATA_FPCI_BAR5_START_MASK			(0xfffffff << 4)
> +#define SATA_FPCI_BAR5_START				(0x0040020 << 4)
> +#define SATA_FPCI_BAR5_ACCESS_TYPE			(0x1)
>   
>   #define SATA_INTR_MASK					0x188
>   #define SATA_INTR_MASK_IP_INT_MASK			BIT(16)
>   
> +#define T_SATA0_CFG_35					0x94
> +#define T_SATA0_CFG_35_IDP_INDEX_MASK			(0x7ff << 2)
> +#define T_SATA0_CFG_35_IDP_INDEX			(0x2a << 2)
> +
> +#define T_SATA0_AHCI_IDP1				0x98
> +#define T_SATA0_AHCI_IDP1_DATA				(0x400040)
> +
> +#define T_SATA0_CFG_PHY_1				0x12c
> +#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN			BIT(23)
> +#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
> +
> +#define T_SATA0_NVOOB                                   0x114
> +#define T_SATA0_NVOOB_COMMA_CNT_MASK                    (0xff << 16)
> +#define T_SATA0_NVOOB_COMMA_CNT                         (0x07 << 16)
> +#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK          (0x3 << 24)
> +#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 24)
> +#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK        (0x3 << 26)
> +#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH             (0x3 << 26)
> +
> +#define T_SATA_CFG_PHY_0                                0x120
> +#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD     BIT(11)
> +#define T_SATA_CFG_PHY_0_MASK_SQUELCH                   BIT(24)
> +
> +#define T_SATA0_CFG2NVOOB_2				0x134
> +#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK	(0x1ff << 18)
> +#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW	(0xc << 18)
> +
>   #define T_SATA0_AHCI_HBA_CAP_BKDR			0x300
> +#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP	BIT(13)
> +#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP	BIT(14)
> +#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP			BIT(26)
> +#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM		BIT(17)
> +#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ			BIT(30)
>   
>   #define T_SATA0_BKDOOR_CC				0x4a4
> +#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK		(0xffff << 16)
> +#define T_SATA0_BKDOOR_CC_CLASS_CODE			(0x0106 << 16)
> +#define T_SATA0_BKDOOR_CC_PROG_IF_MASK			(0xff << 8)
> +#define T_SATA0_BKDOOR_CC_PROG_IF			(0x01 << 8)
>   
>   #define T_SATA0_CFG_SATA				0x54c
>   #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN		BIT(12)
> @@ -82,6 +121,27 @@
>   #define T_SATA0_CHX_PHY_CTRL11				0x6d0
>   #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ		(0x2800 << 16)
>   
> +#define T_SATA0_CHX_PHY_CTRL17_0			0x6e8
> +#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1	0x55010000
> +#define T_SATA0_CHX_PHY_CTRL18_0			0x6ec
> +#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2	0x55010000
> +#define T_SATA0_CHX_PHY_CTRL20_0			0x6f4
> +#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1	0x1
> +#define T_SATA0_CHX_PHY_CTRL21_0			0x6f8
> +#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2	0x1
> +
> +/* AUX Registers */
> +#define SATA_AUX_MISC_CNTL_1_0				0x8
> +#define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE		BIT(17)
> +#define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT		BIT(13)
> +#define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT		BIT(15)
> +
> +#define SATA_AUX_RX_STAT_INT_0				0xc
> +#define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP		BIT(7)
> +
> +#define SATA_AUX_SPARE_CFG0_0				0x18
> +#define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID	BIT(14)
> +
>   #define FUSE_SATA_CALIB					0x124
>   #define FUSE_SATA_CALIB_MASK				0x3
>   
> @@ -99,6 +159,14 @@ static const struct sata_pad_calibration tegra124_pad_calibration[] = {
>   	{0x14, 0x0e, 0x1a, 0x0e},
>   };
>   
> +struct tegra_ahci_ops {
> +	int (*init)(struct ahci_host_priv *hpriv);
> +};
> +
> +struct tegra_ahci_soc {
> +	struct tegra_ahci_ops	ops;
> +};
> +
>   struct tegra_ahci_priv {
>   	struct platform_device	   *pdev;
>   	void __iomem		   *sata_regs;
> @@ -108,6 +176,57 @@ struct tegra_ahci_priv {
>   	/* Needs special handling, cannot use ahci_platform */
>   	struct clk		   *sata_clk;
>   	struct regulator_bulk_data supplies[5];
> +	struct tegra_ahci_soc	   *soc_data;
> +};
> +
> +static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
> +{
> +	struct tegra_ahci_priv *tegra = hpriv->plat_data;
> +	struct sata_pad_calibration calib;
> +	int ret;
> +	u32 val;
> +
> +	/* Pad calibration */
> +	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
> +	if (ret)
> +		return ret;
> +
> +	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
> +
> +	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
> +
> +	val = readl(tegra->sata_regs +
> +		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
> +	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
> +	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
> +	val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
> +	val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET +
> +	       T_SATA0_CHX_PHY_CTRL1_GEN1);
> +
> +	val = readl(tegra->sata_regs +
> +		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
> +	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
> +	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
> +	val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
> +	val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET +
> +	       T_SATA0_CHX_PHY_CTRL1_GEN2);
> +
> +	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
> +	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
> +	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
> +	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
> +
> +	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
> +
> +	return 0;
> +}
> +
> +static const struct tegra_ahci_soc tegra124_ahci_soc_data = {
> +	.ops = {
> +		.init = tegra124_ahci_init,
> +	},
>   };

I would prefer this struct definition to be just above the of_device_id 
table

>   
>   static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
> @@ -145,7 +264,6 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
>   
>   disable_regulators:
>   	regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies);
> -
>   	return ret;
>   }
>   
> @@ -169,8 +287,7 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
>   {
>   	struct tegra_ahci_priv *tegra = hpriv->plat_data;
>   	int ret;
> -	unsigned int val;
> -	struct sata_pad_calibration calib;
> +	u32 val;
>   
>   	ret = tegra_ahci_power_on(hpriv);
>   	if (ret) {
> @@ -179,78 +296,114 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
>   		return ret;
>   	}
>   
> +	/*
> +	 * Program the following SATA IPFS registers
> +	 * to allow SW accesses to SATA's MMIO register range.
> +	 */
> +	val = readl(tegra->sata_regs + SATA_FPCI_BAR5);
> +	val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE);
> +	val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE;
> +	writel(val, tegra->sata_regs + SATA_FPCI_BAR5);
> +
> +	/* Program the following SATA IPFS register to enable the SATA */
>   	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
> -	val |= SATA_CONFIGURATION_EN_FPCI;
> +	val |= SATA_CONFIGURATION_0_EN_FPCI;
>   	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
>   
> -	/* Pad calibration */
> -
> -	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
> -	if (ret) {
> -		dev_err(&tegra->pdev->dev,
> -			"failed to read calibration fuse: %d\n", ret);
> -		return ret;
> -	}
> -
> -	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
> -
> -	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
> -
> -	val = readl(tegra->sata_regs +
> -		SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
> -	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
> -	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
> -	val |= calib.gen1_tx_amp <<
> -			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
> -	val |= calib.gen1_tx_peak <<
> -			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
> -	writel(val, tegra->sata_regs + SCFG_OFFSET +
> -		T_SATA0_CHX_PHY_CTRL1_GEN1);
> -
> -	val = readl(tegra->sata_regs +
> -			SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
> -	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
> -	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
> -	val |= calib.gen2_tx_amp <<
> -			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
> -	val |= calib.gen2_tx_peak <<
> -			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
> -	writel(val, tegra->sata_regs + SCFG_OFFSET +
> -		T_SATA0_CHX_PHY_CTRL1_GEN2);
> -
> -	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
> -		tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
> -	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
> -		tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
> -
> -	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
> -
> -	/* Program controller device ID */
> +	/* Electrical settings for better link stability */
> +	val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0);
> +	val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0);
> +	val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0);
> +	val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0);
> +
> +	/* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */
> +
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
> +	val |= T_SATA_CFG_PHY_0_MASK_SQUELCH;
> +	val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
> +
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
> +	val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK |
> +		 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
> +		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
> +	val |= (T_SATA0_NVOOB_COMMA_CNT |
> +		T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
> +		T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
> +
> +	/*
> +	 * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns
> +	 */
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
> +	val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
> +	val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
> +
> +	if (tegra->soc_data->ops.init)
> +		tegra->soc_data->ops.init(hpriv);
> +
> +	/*
> +	 * Program the following SATA configuration registers
> +	 * to initialize SATA
> +	 */
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
> +	val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
> +		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR);
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
> +	val = T_SATA0_CFG_9_BASE_ADDRESS;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
>   
> +	/* Program Class Code and Programming interface for SATA */
>   	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
>   	val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
>   	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
>   
> -	writel(0x01060100, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
> +	val &=
> +	    ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK |
> +	      T_SATA0_BKDOOR_CC_PROG_IF_MASK);
> +	val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
>   
>   	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
>   	val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
>   	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
>   
> -	/* Enable IO & memory access, bus master mode */
> -
> -	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
> -	val |= T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
> -		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR;
> -	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
> -
> -	/* Program SATA MMIO */
> -
> -	writel(0x10000 << SATA_FPCI_BAR5_START_SHIFT,
> -	       tegra->sata_regs + SATA_FPCI_BAR5);
> +	/* Enabling LPM capabilities through Backdoor Programming */
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
> +	val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP |
> +		T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP |
> +		T_SATA0_AHCI_HBA_CAP_BKDR_SALP |
> +		T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM);
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
> +
> +	/* SATA Second Level Clock Gating configuration
> +	 * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane
> +	 * IDDQ Signals
> +	 */
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
> +	val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK;
> +	val |= T_SATA0_CFG_35_IDP_INDEX;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
> +
> +	val = T_SATA0_AHCI_IDP1_DATA;
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1);
> +
> +	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
> +	val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN |
> +		T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN);
> +	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
> +
> +	/* Enabling IPFS Clock Gating */
> +	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
> +	val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE;
> +	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
>   
> -	writel(0x08000 << T_SATA0_CFG_9_BASE_ADDRESS_SHIFT,
> -	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
>   
>   	/* Unmask SATA interrupts */
>   
> @@ -286,7 +439,10 @@ static const struct ata_port_info ahci_tegra_port_info = {
>   };
>   
>   static const struct of_device_id tegra_ahci_of_match[] = {
> -	{ .compatible = "nvidia,tegra124-ahci" },
> +	{
> +		.compatible = "nvidia,tegra124-ahci",
> +		.data = &tegra124_ahci_soc_data
> +	},
>   	{}
>   };
>   MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
> @@ -301,6 +457,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
>   	struct tegra_ahci_priv *tegra;
>   	struct resource *res;
>   	int ret;
> +	unsigned int i;

This variable doesn't seem to be used here.

>   
>   	hpriv = ahci_platform_get_resources(pdev);
>   	if (IS_ERR(hpriv))
> @@ -313,6 +470,8 @@ static int tegra_ahci_probe(struct platform_device *pdev)
>   	hpriv->plat_data = tegra;
>   
>   	tegra->pdev = pdev;
> +	tegra->soc_data =
> +	    (struct tegra_ahci_soc *)of_device_get_match_data(&pdev->dev);
>   
>   	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>   	tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);
> 

Otherwise looks good to me.

Mikko
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Preetham Chandru Ramchandra Feb. 12, 2018, 5:10 p.m. UTC | #2
DQoNCj4tLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPkZyb206IE1pa2tvIFBlcnR0dW5lbiBb
bWFpbHRvOmN5bmRpc0BrYXBzaS5maV0NCj5TZW50OiBUdWVzZGF5LCBKYW51YXJ5IDIzLCAyMDE4
IDk6MTQgUE0NCj5UbzogUHJlZXRoYW0gQ2hhbmRydSA8cGNoYW5kcnVAbnZpZGlhLmNvbT47IHRo
aWVycnkucmVkaW5nQGdtYWlsLmNvbTsNCj50akBrZXJuZWwub3JnDQo+Q2M6IHByZWV0aGFtMjYw
QGdtYWlsLmNvbTsgbGludXgtdGVncmFAdmdlci5rZXJuZWwub3JnOyBsaW51eC0NCj5pZGVAdmdl
ci5rZXJuZWwub3JnOyBWZW51IEJ5cmF2YXJhc3UgPHZieXJhdmFyYXN1QG52aWRpYS5jb20+OyBQ
YXZhbg0KPkt1bmFwdWxpIDxwa3VuYXB1bGlAbnZpZGlhLmNvbT4NCj5TdWJqZWN0OiBSZTogW1BB
VENIIFY2IDMvN10gYXRhOiBhaGNpX3RlZ3JhOiBVcGRhdGUgaW5pdGlhbGl6YXRpb24gc2VxdWVu
Y2UNCj4NCj5PbiAwMS8wOS8yMDE4IDA5OjE3IEFNLCBQcmVldGhhbSBDaGFuZHJ1IFJhbWNoYW5k
cmEgd3JvdGU6DQo+PiBGcm9tOiBQcmVldGhhbSBSYW1jaGFuZHJhIDxwY2hhbmRydUBudmlkaWEu
Y29tPg0KPj4NCj4+IFVwZGF0ZSB0aGUgY29udHJvbGxlciBpbml0aWFsaXphdGlvbiBzZXF1ZW5j
ZSBhbmQgbW92ZQ0KPj4gdDEyNCBzcGVjaWZpY3MgdG8gdGVncmExMjRfYWhjaV9pbml0Lg0KPj4N
Cj4+IFNpZ25lZC1vZmYtYnk6IFByZWV0aGFtIENoYW5kcnUgUiA8cGNoYW5kcnVAbnZpZGlhLmNv
bT4NCj4+IC0tLQ0KPj4gICBkcml2ZXJzL2F0YS9haGNpX3RlZ3JhLmMgfCAyODkgKysrKysrKysr
KysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLQ0KPi0tLS0tLS0NCj4+ICAgMSBmaWxlIGNo
YW5nZWQsIDIyNCBpbnNlcnRpb25zKCspLCA2NSBkZWxldGlvbnMoLSkNCj4+DQo+PiBkaWZmIC0t
Z2l0IGEvZHJpdmVycy9hdGEvYWhjaV90ZWdyYS5jIGIvZHJpdmVycy9hdGEvYWhjaV90ZWdyYS5j
IGluZGV4DQo+PiAzYTYyZWIyNDZkODAuLjcxODUwZTk2ZTc4NyAxMDA2NDQNCj4+IC0tLSBhL2Ry
aXZlcnMvYXRhL2FoY2lfdGVncmEuYw0KPj4gKysrIGIvZHJpdmVycy9hdGEvYWhjaV90ZWdyYS5j
DQo+PiBAQCAtMzQsNyArMzQsOCBAQA0KPj4gICAjZGVmaW5lIERSVl9OQU1FICJ0ZWdyYS1haGNp
Ig0KPj4NCj4+ICAgI2RlZmluZSBTQVRBX0NPTkZJR1VSQVRJT05fMAkJCQkweDE4MA0KPj4gLSNk
ZWZpbmUgU0FUQV9DT05GSUdVUkFUSU9OX0VOX0ZQQ0kJCQlCSVQoMCkNCj4+ICsjZGVmaW5lIFNB
VEFfQ09ORklHVVJBVElPTl8wX0VOX0ZQQ0kJCQlCSVQoMCkNCj4+ICsjZGVmaW5lIFNBVEFfQ09O
RklHVVJBVElPTl8wX0NMS19PVkVSUklERQkJCUJJVCgzMSkNCj4+DQo+PiAgICNkZWZpbmUgU0NG
R19PRkZTRVQJCQkJCTB4MTAwMA0KPj4NCj4+IEBAIC00NSwxNyArNDYsNTUgQEANCj4+ICAgI2Rl
ZmluZSBUX1NBVEEwX0NGR18xX1NFUlIJCQkJQklUKDgpDQo+Pg0KPj4gICAjZGVmaW5lIFRfU0FU
QTBfQ0ZHXzkJCQkJCTB4MjQNCj4+IC0jZGVmaW5lIFRfU0FUQTBfQ0ZHXzlfQkFTRV9BRERSRVNT
X1NISUZUCQkxMw0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfOV9CQVNFX0FERFJFU1MJCQkweDQw
MDIwMDAwDQo+Pg0KPj4gICAjZGVmaW5lIFNBVEFfRlBDSV9CQVI1CQkJCQkweDk0DQo+PiAtI2Rl
ZmluZSBTQVRBX0ZQQ0lfQkFSNV9TVEFSVF9TSElGVAkJCTQNCj4+ICsjZGVmaW5lIFNBVEFfRlBD
SV9CQVI1X1NUQVJUX01BU0sJCQkoMHhmZmZmZmZmIDw8IDQpDQo+PiArI2RlZmluZSBTQVRBX0ZQ
Q0lfQkFSNV9TVEFSVAkJCQkoMHgwMDQwMDIwIDw8DQo+NCkNCj4+ICsjZGVmaW5lIFNBVEFfRlBD
SV9CQVI1X0FDQ0VTU19UWVBFCQkJKDB4MSkNCj4+DQo+PiAgICNkZWZpbmUgU0FUQV9JTlRSX01B
U0sJCQkJCTB4MTg4DQo+PiAgICNkZWZpbmUgU0FUQV9JTlRSX01BU0tfSVBfSU5UX01BU0sJCQlC
SVQoMTYpDQo+Pg0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfMzUJCQkJCTB4OTQNCj4+ICsjZGVm
aW5lIFRfU0FUQTBfQ0ZHXzM1X0lEUF9JTkRFWF9NQVNLCQkJKDB4N2ZmIDw8IDIpDQo+PiArI2Rl
ZmluZSBUX1NBVEEwX0NGR18zNV9JRFBfSU5ERVgJCQkoMHgyYSA8PCAyKQ0KPj4gKw0KPj4gKyNk
ZWZpbmUgVF9TQVRBMF9BSENJX0lEUDEJCQkJMHg5OA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9BSENJ
X0lEUDFfREFUQQkJCQkoMHg0MDAwNDApDQo+PiArDQo+PiArI2RlZmluZSBUX1NBVEEwX0NGR19Q
SFlfMQkJCQkweDEyYw0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfUEhZXzFfUEFEU19JRERRX0VO
CQkJQklUKDIzKQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkdfUEhZXzFfUEFEX1BMTF9JRERRX0VO
CQlCSVQoMjIpDQo+PiArDQo+PiArI2RlZmluZSBUX1NBVEEwX05WT09CICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAweDExNA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9OVk9PQl9DT01N
QV9DTlRfTUFTSyAgICAgICAgICAgICAgICAgICAgKDB4ZmYgPDwgMTYpDQo+PiArI2RlZmluZSBU
X1NBVEEwX05WT09CX0NPTU1BX0NOVCAgICAgICAgICAgICAgICAgICAgICAgICAoMHgwNyA8PCAx
NikNCj4+ICsjZGVmaW5lIFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTU9ERV9NQVNLICAg
ICAgICAgICgweDMgPDwgMjQpDQo+PiArI2RlZmluZSBUX1NBVEEwX05WT09CX1NRVUVMQ0hfRklM
VEVSX01PREUgICAgICAgICAgICAgICAoMHgxIDw8IDI0KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9O
Vk9PQl9TUVVFTENIX0ZJTFRFUl9MRU5HVEhfTUFTSyAgICAgICAgKDB4MyA8PCAyNikNCj4+ICsj
ZGVmaW5lIFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTEVOR1RIICAgICAgICAgICAgICgw
eDMgPDwgMjYpDQo+PiArDQo+PiArI2RlZmluZSBUX1NBVEFfQ0ZHX1BIWV8wICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAweDEyMA0KPj4gKyNkZWZpbmUgVF9TQVRBX0NGR19QSFlfMF9V
U0VfN0JJVF9BTElHTl9ERVRfRk9SX1NQRCAgICAgQklUKDExKQ0KPj4gKyNkZWZpbmUgVF9TQVRB
X0NGR19QSFlfMF9NQVNLX1NRVUVMQ0ggICAgICAgICAgICAgICAgICAgQklUKDI0KQ0KPj4gKw0K
Pj4gKyNkZWZpbmUgVF9TQVRBMF9DRkcyTlZPT0JfMgkJCQkweDEzNA0KPj4gKyNkZWZpbmUgVF9T
QVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lETEVfQ05UX0xPV19NQVNLCSgweDFmZg0KPjw8IDE4
KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lETEVfQ05UX0xPVwko
MHhjIDw8DQo+MTgpDQo+PiArDQo+PiAgICNkZWZpbmUgVF9TQVRBMF9BSENJX0hCQV9DQVBfQktE
UgkJCTB4MzAwDQo+PiArI2RlZmluZSBUX1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1BBUlRJQUxf
U1RfQ0FQCUJJVCgxMykNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQUhDSV9IQkFfQ0FQX0JLRFJfU0xV
TUJFUl9TVF9DQVAJQklUKDE0KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9BSENJX0hCQV9DQVBfQktE
Ul9TQUxQCQkJQklUKDI2KQ0KPj4gKyNkZWZpbmUgVF9TQVRBMF9BSENJX0hCQV9DQVBfQktEUl9T
VVBQX1BNCQlCSVQoMTcpDQo+PiArI2RlZmluZSBUX1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1NO
Q1EJCQlCSVQoMzApDQo+Pg0KPj4gICAjZGVmaW5lIFRfU0FUQTBfQktET09SX0NDCQkJCTB4NGE0
DQo+PiArI2RlZmluZSBUX1NBVEEwX0JLRE9PUl9DQ19DTEFTU19DT0RFX01BU0sJCSgweGZmZmYg
PDwgMTYpDQo+PiArI2RlZmluZSBUX1NBVEEwX0JLRE9PUl9DQ19DTEFTU19DT0RFCQkJKDB4MDEw
NiA8PCAxNikNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQktET09SX0NDX1BST0dfSUZfTUFTSwkJCSgw
eGZmIDw8DQo+OCkNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQktET09SX0NDX1BST0dfSUYJCQkoMHgw
MSA8PCA4KQ0KPj4NCj4+ICAgI2RlZmluZSBUX1NBVEEwX0NGR19TQVRBCQkJCTB4NTRjDQo+PiAg
ICNkZWZpbmUgVF9TQVRBMF9DRkdfU0FUQV9CQUNLRE9PUl9QUk9HX0lGX0VOCQlCSVQoMTIpDQo+
PiBAQCAtODIsNiArMTIxLDI3IEBADQo+PiAgICNkZWZpbmUgVF9TQVRBMF9DSFhfUEhZX0NUUkwx
MQkJCQkweDZkMA0KPj4gICAjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMTFfR0VOMl9SWF9F
UQkJKDB4MjgwMCA8PCAxNikNCj4+DQo+PiArI2RlZmluZSBUX1NBVEEwX0NIWF9QSFlfQ1RSTDE3
XzAJCQkweDZlOA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DSFhfUEhZX0NUUkwxN18wX1JYX0VRX0NU
UkxfTF9HRU4xCTB4NTUwMTAwMDANCj4+ICsjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMThf
MAkJCTB4NmVjDQo+PiArI2RlZmluZSBUX1NBVEEwX0NIWF9QSFlfQ1RSTDE4XzBfUlhfRVFfQ1RS
TF9MX0dFTjIJMHg1NTAxMDAwMA0KPj4gKyNkZWZpbmUgVF9TQVRBMF9DSFhfUEhZX0NUUkwyMF8w
CQkJMHg2ZjQNCj4+ICsjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMjBfMF9SWF9FUV9DVFJM
X0hfR0VOMQkweDENCj4+ICsjZGVmaW5lIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMjFfMAkJCTB4NmY4
DQo+PiArI2RlZmluZSBUX1NBVEEwX0NIWF9QSFlfQ1RSTDIxXzBfUlhfRVFfQ1RSTF9IX0dFTjIJ
MHgxDQo+PiArDQo+PiArLyogQVVYIFJlZ2lzdGVycyAqLw0KPj4gKyNkZWZpbmUgU0FUQV9BVVhf
TUlTQ19DTlRMXzFfMAkJCQkweDgNCj4+ICsjZGVmaW5lIFNBVEFfQVVYX01JU0NfQ05UTF8xXzBf
REVWU0xQX09WRVJSSURFCQlCSVQoMTcpDQo+PiArI2RlZmluZSBTQVRBX0FVWF9NSVNDX0NOVExf
MV8wX1NEU19TVVBQT1JUCQlCSVQoMTMpDQo+PiArI2RlZmluZSBTQVRBX0FVWF9NSVNDX0NOVExf
MV8wX0RFU09fU1VQUE9SVAkJQklUKDE1KQ0KPj4gKw0KPj4gKyNkZWZpbmUgU0FUQV9BVVhfUlhf
U1RBVF9JTlRfMAkJCQkweGMNCj4+ICsjZGVmaW5lIFNBVEFfQVVYX1JYX1NUQVRfSU5UXzBfU0FU
QV9ERVZTTFAJCUJJVCg3KQ0KPj4gKw0KPj4gKyNkZWZpbmUgU0FUQV9BVVhfU1BBUkVfQ0ZHMF8w
CQkJCTB4MTgNCj4+ICsjZGVmaW5lIFNBVEFfQVVYX1NQQVJFX0NGRzBfMF9NREFUX1RJTUVSX0FG
VEVSX1BHX1ZBTElECUJJVCgxNCkNCj4+ICsNCj4+ICAgI2RlZmluZSBGVVNFX1NBVEFfQ0FMSUIJ
CQkJCTB4MTI0DQo+PiAgICNkZWZpbmUgRlVTRV9TQVRBX0NBTElCX01BU0sJCQkJMHgzDQo+Pg0K
Pj4gQEAgLTk5LDYgKzE1OSwxNCBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IHNhdGFfcGFkX2NhbGli
cmF0aW9uDQo+dGVncmExMjRfcGFkX2NhbGlicmF0aW9uW10gPSB7DQo+PiAgIAl7MHgxNCwgMHgw
ZSwgMHgxYSwgMHgwZX0sDQo+PiAgIH07DQo+Pg0KPj4gK3N0cnVjdCB0ZWdyYV9haGNpX29wcyB7
DQo+PiArCWludCAoKmluaXQpKHN0cnVjdCBhaGNpX2hvc3RfcHJpdiAqaHByaXYpOyB9Ow0KPj4g
Kw0KPj4gK3N0cnVjdCB0ZWdyYV9haGNpX3NvYyB7DQo+PiArCXN0cnVjdCB0ZWdyYV9haGNpX29w
cwlvcHM7DQo+PiArfTsNCj4+ICsNCj4+ICAgc3RydWN0IHRlZ3JhX2FoY2lfcHJpdiB7DQo+PiAg
IAlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlCSAgICpwZGV2Ow0KPj4gICAJdm9pZCBfX2lvbWVtCQkg
ICAqc2F0YV9yZWdzOw0KPj4gQEAgLTEwOCw2ICsxNzYsNTcgQEAgc3RydWN0IHRlZ3JhX2FoY2lf
cHJpdiB7DQo+PiAgIAkvKiBOZWVkcyBzcGVjaWFsIGhhbmRsaW5nLCBjYW5ub3QgdXNlIGFoY2lf
cGxhdGZvcm0gKi8NCj4+ICAgCXN0cnVjdCBjbGsJCSAgICpzYXRhX2NsazsNCj4+ICAgCXN0cnVj
dCByZWd1bGF0b3JfYnVsa19kYXRhIHN1cHBsaWVzWzVdOw0KPj4gKwlzdHJ1Y3QgdGVncmFfYWhj
aV9zb2MJICAgKnNvY19kYXRhOw0KPj4gK307DQo+PiArDQo+PiArc3RhdGljIGludCB0ZWdyYTEy
NF9haGNpX2luaXQoc3RydWN0IGFoY2lfaG9zdF9wcml2ICpocHJpdikgew0KPj4gKwlzdHJ1Y3Qg
dGVncmFfYWhjaV9wcml2ICp0ZWdyYSA9IGhwcml2LT5wbGF0X2RhdGE7DQo+PiArCXN0cnVjdCBz
YXRhX3BhZF9jYWxpYnJhdGlvbiBjYWxpYjsNCj4+ICsJaW50IHJldDsNCj4+ICsJdTMyIHZhbDsN
Cj4+ICsNCj4+ICsJLyogUGFkIGNhbGlicmF0aW9uICovDQo+PiArCXJldCA9IHRlZ3JhX2Z1c2Vf
cmVhZGwoRlVTRV9TQVRBX0NBTElCLCAmdmFsKTsNCj4+ICsJaWYgKHJldCkNCj4+ICsJCXJldHVy
biByZXQ7DQo+PiArDQo+PiArCWNhbGliID0gdGVncmExMjRfcGFkX2NhbGlicmF0aW9uW3ZhbCAm
IEZVU0VfU0FUQV9DQUxJQl9NQVNLXTsNCj4+ICsNCj4+ICsJd3JpdGVsKEJJVCgwKSwgdGVncmEt
PnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9JTkRFWCk7DQo+PiArDQo+PiArCXZh
bCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKw0KPj4gKwkJICAgIFNDRkdfT0ZGU0VUICsgVF9T
QVRBMF9DSFhfUEhZX0NUUkwxX0dFTjEpOw0KPj4gKwl2YWwgJj0gflRfU0FUQTBfQ0hYX1BIWV9D
VFJMMV9HRU4xX1RYX0FNUF9NQVNLOw0KPj4gKwl2YWwgJj0gflRfU0FUQTBfQ0hYX1BIWV9DVFJM
MV9HRU4xX1RYX1BFQUtfTUFTSzsNCj4+ICsJdmFsIHw9IGNhbGliLmdlbjFfdHhfYW1wIDw8DQo+
VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfQU1QX1NISUZUOw0KPj4gKwl2YWwgfD0gY2Fs
aWIuZ2VuMV90eF9wZWFrIDw8DQo+VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfUEVBS19T
SElGVDsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsN
Cj4+ICsJICAgICAgIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9HRU4xKTsNCj4+ICsNCj4+ICsJdmFs
ID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArDQo+PiArCQkgICAgU0NGR19PRkZTRVQgKyBUX1NB
VEEwX0NIWF9QSFlfQ1RSTDFfR0VOMik7DQo+PiArCXZhbCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NU
UkwxX0dFTjJfVFhfQU1QX01BU0s7DQo+PiArCXZhbCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NUUkwx
X0dFTjJfVFhfUEVBS19NQVNLOw0KPj4gKwl2YWwgfD0gY2FsaWIuZ2VuMl90eF9hbXAgPDwNCj5U
X1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMV9UWF9BTVBfU0hJRlQ7DQo+PiArCXZhbCB8PSBjYWxp
Yi5nZW4yX3R4X3BlYWsgPDwNCj5UX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMV9UWF9QRUFLX1NI
SUZUOw0KPj4gKwl3cml0ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0K
Pj4gKwkgICAgICAgVF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjIpOw0KPj4gKw0KPj4gKwl3cml0
ZWwoVF9TQVRBMF9DSFhfUEhZX0NUUkwxMV9HRU4yX1JYX0VRLA0KPj4gKwkgICAgICAgdGVncmEt
PnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DSFhfUEhZX0NUUkwxMSk7DQo+PiAr
CXdyaXRlbChUX1NBVEEwX0NIWF9QSFlfQ1RSTDJfQ0RSX0NOVExfR0VOMSwNCj4+ICsJICAgICAg
IHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMik7
DQo+PiArDQo+PiArCXdyaXRlbCgwLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBU
X1NBVEEwX0lOREVYKTsNCj4+ICsNCj4+ICsJcmV0dXJuIDA7DQo+PiArfQ0KPj4gKw0KPj4gK3N0
YXRpYyBjb25zdCBzdHJ1Y3QgdGVncmFfYWhjaV9zb2MgdGVncmExMjRfYWhjaV9zb2NfZGF0YSA9
IHsNCj4+ICsJLm9wcyA9IHsNCj4+ICsJCS5pbml0ID0gdGVncmExMjRfYWhjaV9pbml0LA0KPj4g
Kwl9LA0KPj4gICB9Ow0KPg0KPkkgd291bGQgcHJlZmVyIHRoaXMgc3RydWN0IGRlZmluaXRpb24g
dG8gYmUganVzdCBhYm92ZSB0aGUgb2ZfZGV2aWNlX2lkIHRhYmxlDQo+DQpva2F5DQo+Pg0KPj4g
ICBzdGF0aWMgaW50IHRlZ3JhX2FoY2lfcG93ZXJfb24oc3RydWN0IGFoY2lfaG9zdF9wcml2ICpo
cHJpdikgQEANCj4+IC0xNDUsNyArMjY0LDYgQEAgc3RhdGljIGludCB0ZWdyYV9haGNpX3Bvd2Vy
X29uKHN0cnVjdCBhaGNpX2hvc3RfcHJpdg0KPj4gKmhwcml2KQ0KPj4NCj4+ICAgZGlzYWJsZV9y
ZWd1bGF0b3JzOg0KPj4gICAJcmVndWxhdG9yX2J1bGtfZGlzYWJsZShBUlJBWV9TSVpFKHRlZ3Jh
LT5zdXBwbGllcyksDQo+PiB0ZWdyYS0+c3VwcGxpZXMpOw0KPj4gLQ0KPj4gICAJcmV0dXJuIHJl
dDsNCj4+ICAgfQ0KPj4NCj4+IEBAIC0xNjksOCArMjg3LDcgQEAgc3RhdGljIGludCB0ZWdyYV9h
aGNpX2NvbnRyb2xsZXJfaW5pdChzdHJ1Y3QNCj5haGNpX2hvc3RfcHJpdiAqaHByaXYpDQo+PiAg
IHsNCj4+ICAgCXN0cnVjdCB0ZWdyYV9haGNpX3ByaXYgKnRlZ3JhID0gaHByaXYtPnBsYXRfZGF0
YTsNCj4+ICAgCWludCByZXQ7DQo+PiAtCXVuc2lnbmVkIGludCB2YWw7DQo+PiAtCXN0cnVjdCBz
YXRhX3BhZF9jYWxpYnJhdGlvbiBjYWxpYjsNCj4+ICsJdTMyIHZhbDsNCj4+DQo+PiAgIAlyZXQg
PSB0ZWdyYV9haGNpX3Bvd2VyX29uKGhwcml2KTsNCj4+ICAgCWlmIChyZXQpIHsNCj4+IEBAIC0x
NzksNzggKzI5NiwxMTQgQEAgc3RhdGljIGludCB0ZWdyYV9haGNpX2NvbnRyb2xsZXJfaW5pdChz
dHJ1Y3QNCj5haGNpX2hvc3RfcHJpdiAqaHByaXYpDQo+PiAgIAkJcmV0dXJuIHJldDsNCj4+ICAg
CX0NCj4+DQo+PiArCS8qDQo+PiArCSAqIFByb2dyYW0gdGhlIGZvbGxvd2luZyBTQVRBIElQRlMg
cmVnaXN0ZXJzDQo+PiArCSAqIHRvIGFsbG93IFNXIGFjY2Vzc2VzIHRvIFNBVEEncyBNTUlPIHJl
Z2lzdGVyIHJhbmdlLg0KPj4gKwkgKi8NCj4+ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVn
cyArIFNBVEFfRlBDSV9CQVI1KTsNCj4+ICsJdmFsICY9IH4oU0FUQV9GUENJX0JBUjVfU1RBUlRf
TUFTSyB8DQo+U0FUQV9GUENJX0JBUjVfQUNDRVNTX1RZUEUpOw0KPj4gKwl2YWwgfD0gU0FUQV9G
UENJX0JBUjVfU1RBUlQgfCBTQVRBX0ZQQ0lfQkFSNV9BQ0NFU1NfVFlQRTsNCj4+ICsJd3JpdGVs
KHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNBVEFfRlBDSV9CQVI1KTsNCj4+ICsNCj4+ICsJLyog
UHJvZ3JhbSB0aGUgZm9sbG93aW5nIFNBVEEgSVBGUyByZWdpc3RlciB0byBlbmFibGUgdGhlIFNB
VEEgKi8NCj4+ICAgCXZhbCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQVRBX0NPTkZJR1VS
QVRJT05fMCk7DQo+PiAtCXZhbCB8PSBTQVRBX0NPTkZJR1VSQVRJT05fRU5fRlBDSTsNCj4+ICsJ
dmFsIHw9IFNBVEFfQ09ORklHVVJBVElPTl8wX0VOX0ZQQ0k7DQo+PiAgIAl3cml0ZWwodmFsLCB0
ZWdyYS0+c2F0YV9yZWdzICsgU0FUQV9DT05GSUdVUkFUSU9OXzApOw0KPj4NCj4+IC0JLyogUGFk
IGNhbGlicmF0aW9uICovDQo+PiAtDQo+PiAtCXJldCA9IHRlZ3JhX2Z1c2VfcmVhZGwoRlVTRV9T
QVRBX0NBTElCLCAmdmFsKTsNCj4+IC0JaWYgKHJldCkgew0KPj4gLQkJZGV2X2VycigmdGVncmEt
PnBkZXYtPmRldiwNCj4+IC0JCQkiZmFpbGVkIHRvIHJlYWQgY2FsaWJyYXRpb24gZnVzZTogJWRc
biIsIHJldCk7DQo+PiAtCQlyZXR1cm4gcmV0Ow0KPj4gLQl9DQo+PiAtDQo+PiAtCWNhbGliID0g
dGVncmExMjRfcGFkX2NhbGlicmF0aW9uW3ZhbCAmIEZVU0VfU0FUQV9DQUxJQl9NQVNLXTsNCj4+
IC0NCj4+IC0Jd3JpdGVsKEJJVCgwKSwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsg
VF9TQVRBMF9JTkRFWCk7DQo+PiAtDQo+PiAtCXZhbCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3Mg
Kw0KPj4gLQkJU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMSk7DQo+PiAt
CXZhbCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfQU1QX01BU0s7DQo+PiAtCXZh
bCAmPSB+VF9TQVRBMF9DSFhfUEhZX0NUUkwxX0dFTjFfVFhfUEVBS19NQVNLOw0KPj4gLQl2YWwg
fD0gY2FsaWIuZ2VuMV90eF9hbXAgPDwNCj4+IC0JCQlUX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VO
MV9UWF9BTVBfU0hJRlQ7DQo+PiAtCXZhbCB8PSBjYWxpYi5nZW4xX3R4X3BlYWsgPDwNCj4+IC0J
CQlUX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMV9UWF9QRUFLX1NISUZUOw0KPj4gLQl3cml0ZWwo
dmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0KPj4gLQkJVF9TQVRBMF9DSFhf
UEhZX0NUUkwxX0dFTjEpOw0KPj4gLQ0KPj4gLQl2YWwgPSByZWFkbCh0ZWdyYS0+c2F0YV9yZWdz
ICsNCj4+IC0JCQlTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9HRU4yKTsNCj4+
IC0JdmFsICY9IH5UX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMl9UWF9BTVBfTUFTSzsNCj4+IC0J
dmFsICY9IH5UX1NBVEEwX0NIWF9QSFlfQ1RSTDFfR0VOMl9UWF9QRUFLX01BU0s7DQo+PiAtCXZh
bCB8PSBjYWxpYi5nZW4yX3R4X2FtcCA8PA0KPj4gLQkJCVRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9H
RU4xX1RYX0FNUF9TSElGVDsNCj4+IC0JdmFsIHw9IGNhbGliLmdlbjJfdHhfcGVhayA8PA0KPj4g
LQkJCVRfU0FUQTBfQ0hYX1BIWV9DVFJMMV9HRU4xX1RYX1BFQUtfU0hJRlQ7DQo+PiAtCXdyaXRl
bCh2YWwsIHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+PiAtCQlUX1NBVEEwX0NI
WF9QSFlfQ1RSTDFfR0VOMik7DQo+PiAtDQo+PiAtCXdyaXRlbChUX1NBVEEwX0NIWF9QSFlfQ1RS
TDExX0dFTjJfUlhfRVEsDQo+PiAtCQl0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBU
X1NBVEEwX0NIWF9QSFlfQ1RSTDExKTsNCj4+IC0Jd3JpdGVsKFRfU0FUQTBfQ0hYX1BIWV9DVFJM
Ml9DRFJfQ05UTF9HRU4xLA0KPj4gLQkJdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsg
VF9TQVRBMF9DSFhfUEhZX0NUUkwyKTsNCj4+IC0NCj4+IC0Jd3JpdGVsKDAsIHRlZ3JhLT5zYXRh
X3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfSU5ERVgpOw0KPj4gLQ0KPj4gLQkvKiBQcm9n
cmFtIGNvbnRyb2xsZXIgZGV2aWNlIElEICovDQo+PiArCS8qIEVsZWN0cmljYWwgc2V0dGluZ3Mg
Zm9yIGJldHRlciBsaW5rIHN0YWJpbGl0eSAqLw0KPj4gKwl2YWwgPSBUX1NBVEEwX0NIWF9QSFlf
Q1RSTDE3XzBfUlhfRVFfQ1RSTF9MX0dFTjE7DQo+PiArCXdyaXRlbCh2YWwsIHRlZ3JhLT5zYXRh
X3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+VF9TQVRBMF9DSFhfUEhZX0NUUkwxN18wKTsNCj4+ICsJ
dmFsID0gVF9TQVRBMF9DSFhfUEhZX0NUUkwxOF8wX1JYX0VRX0NUUkxfTF9HRU4yOw0KPj4gKwl3
cml0ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0KPlRfU0FUQTBfQ0hY
X1BIWV9DVFJMMThfMCk7DQo+PiArCXZhbCA9IFRfU0FUQTBfQ0hYX1BIWV9DVFJMMjBfMF9SWF9F
UV9DVFJMX0hfR0VOMTsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdf
T0ZGU0VUICsNCj5UX1NBVEEwX0NIWF9QSFlfQ1RSTDIwXzApOw0KPj4gKwl2YWwgPSBUX1NBVEEw
X0NIWF9QSFlfQ1RSTDIxXzBfUlhfRVFfQ1RSTF9IX0dFTjI7DQo+PiArCXdyaXRlbCh2YWwsIHRl
Z3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+PiArVF9TQVRBMF9DSFhfUEhZX0NUUkwy
MV8wKTsNCj4+ICsNCj4+ICsJLyogRm9yIFNRVUVMQ0ggRmlsdGVyICYgR2VuMyBkcml2ZSBnZXR0
aW5nIGRldGVjdGVkIGFzIEdlbjEgZHJpdmUgKi8NCj4+ICsNCj4+ICsJdmFsID0gcmVhZGwodGVn
cmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBX0NGR19QSFlfMCk7DQo+PiArCXZh
bCB8PSBUX1NBVEFfQ0ZHX1BIWV8wX01BU0tfU1FVRUxDSDsNCj4+ICsJdmFsICY9IH5UX1NBVEFf
Q0ZHX1BIWV8wX1VTRV83QklUX0FMSUdOX0RFVF9GT1JfU1BEOw0KPj4gKwl3cml0ZWwodmFsLCB0
ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEFfQ0ZHX1BIWV8wKTsNCj4+ICsN
Cj4+ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRB
MF9OVk9PQik7DQo+PiArCXZhbCAmPSB+KFRfU0FUQTBfTlZPT0JfQ09NTUFfQ05UX01BU0sgfA0K
Pj4gKwkJIFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTEVOR1RIX01BU0sgfA0KPj4gKwkJ
IFRfU0FUQTBfTlZPT0JfU1FVRUxDSF9GSUxURVJfTU9ERV9NQVNLKTsNCj4+ICsJdmFsIHw9IChU
X1NBVEEwX05WT09CX0NPTU1BX0NOVCB8DQo+PiArCQlUX1NBVEEwX05WT09CX1NRVUVMQ0hfRklM
VEVSX0xFTkdUSCB8DQo+PiArCQlUX1NBVEEwX05WT09CX1NRVUVMQ0hfRklMVEVSX01PREUpOw0K
Pj4gKwl3cml0ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEw
X05WT09CKTsNCj4+ICsNCj4+ICsJLyoNCj4+ICsJICogQ2hhbmdlIENGRzJOVk9PQl8yX0NPTVdB
S0VfSURMRV9DTlRfTE9XIGZyb20gODMuMyBucyB0bw0KPjU4Ljhucw0KPj4gKwkgKi8NCj4+ICsJ
dmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkcy
TlZPT0JfMik7DQo+PiArCXZhbCAmPSB+VF9TQVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lETEVf
Q05UX0xPV19NQVNLOw0KPj4gKwl2YWwgfD0gVF9TQVRBMF9DRkcyTlZPT0JfMl9DT01XQUtFX0lE
TEVfQ05UX0xPVzsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZG
U0VUICsgVF9TQVRBMF9DRkcyTlZPT0JfMik7DQo+PiArDQo+PiArCWlmICh0ZWdyYS0+c29jX2Rh
dGEtPm9wcy5pbml0KQ0KPj4gKwkJdGVncmEtPnNvY19kYXRhLT5vcHMuaW5pdChocHJpdik7DQo+
PiArDQo+PiArCS8qDQo+PiArCSAqIFByb2dyYW0gdGhlIGZvbGxvd2luZyBTQVRBIGNvbmZpZ3Vy
YXRpb24gcmVnaXN0ZXJzDQo+PiArCSAqIHRvIGluaXRpYWxpemUgU0FUQQ0KPj4gKwkgKi8NCj4+
ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9D
RkdfMSk7DQo+PiArCXZhbCB8PSAoVF9TQVRBMF9DRkdfMV9JT19TUEFDRSB8IFRfU0FUQTBfQ0ZH
XzFfTUVNT1JZX1NQQUNFIHwNCj4+ICsJCVRfU0FUQTBfQ0ZHXzFfQlVTX01BU1RFUiB8IFRfU0FU
QTBfQ0ZHXzFfU0VSUik7DQo+PiArCXdyaXRlbCh2YWwsIHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZH
X09GRlNFVCArIFRfU0FUQTBfQ0ZHXzEpOw0KPj4gKwl2YWwgPSBUX1NBVEEwX0NGR185X0JBU0Vf
QUREUkVTUzsNCj4+ICsJd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VU
ICsgVF9TQVRBMF9DRkdfOSk7DQo+Pg0KPj4gKwkvKiBQcm9ncmFtIENsYXNzIENvZGUgYW5kIFBy
b2dyYW1taW5nIGludGVyZmFjZSBmb3IgU0FUQSAqLw0KPj4gICAJdmFsID0gcmVhZGwodGVncmEt
PnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkdfU0FUQSk7DQo+PiAgIAl2YWwg
fD0gVF9TQVRBMF9DRkdfU0FUQV9CQUNLRE9PUl9QUk9HX0lGX0VOOw0KPj4gICAJd3JpdGVsKHZh
bCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkdfU0FUQSk7DQo+
Pg0KPj4gLQl3cml0ZWwoMHgwMTA2MDEwMCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VU
ICsNCj5UX1NBVEEwX0JLRE9PUl9DQyk7DQo+PiArCXZhbCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3Jl
Z3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQktET09SX0NDKTsNCj4+ICsJdmFsICY9DQo+PiAr
CSAgICB+KFRfU0FUQTBfQktET09SX0NDX0NMQVNTX0NPREVfTUFTSyB8DQo+PiArCSAgICAgIFRf
U0FUQTBfQktET09SX0NDX1BST0dfSUZfTUFTSyk7DQo+PiArCXZhbCB8PSBUX1NBVEEwX0JLRE9P
Ul9DQ19DTEFTU19DT0RFIHwNCj5UX1NBVEEwX0JLRE9PUl9DQ19QUk9HX0lGOw0KPj4gKwl3cml0
ZWwodmFsLCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0JLRE9PUl9D
Qyk7DQo+Pg0KPj4gICAJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VU
ICsgVF9TQVRBMF9DRkdfU0FUQSk7DQo+PiAgIAl2YWwgJj0gflRfU0FUQTBfQ0ZHX1NBVEFfQkFD
S0RPT1JfUFJPR19JRl9FTjsNCj4+ICAgCXdyaXRlbCh2YWwsIHRlZ3JhLT5zYXRhX3JlZ3MgKyBT
Q0ZHX09GRlNFVCArIFRfU0FUQTBfQ0ZHX1NBVEEpOw0KPj4NCj4+IC0JLyogRW5hYmxlIElPICYg
bWVtb3J5IGFjY2VzcywgYnVzIG1hc3RlciBtb2RlICovDQo+PiAtDQo+PiAtCXZhbCA9IHJlYWRs
KHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQ0ZHXzEpOw0KPj4gLQl2
YWwgfD0gVF9TQVRBMF9DRkdfMV9JT19TUEFDRSB8IFRfU0FUQTBfQ0ZHXzFfTUVNT1JZX1NQQUNF
IHwNCj4+IC0JCVRfU0FUQTBfQ0ZHXzFfQlVTX01BU1RFUiB8IFRfU0FUQTBfQ0ZHXzFfU0VSUjsN
Cj4+IC0Jd3JpdGVsKHZhbCwgdGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRB
MF9DRkdfMSk7DQo+PiAtDQo+PiAtCS8qIFByb2dyYW0gU0FUQSBNTUlPICovDQo+PiAtDQo+PiAt
CXdyaXRlbCgweDEwMDAwIDw8IFNBVEFfRlBDSV9CQVI1X1NUQVJUX1NISUZULA0KPj4gLQkgICAg
ICAgdGVncmEtPnNhdGFfcmVncyArIFNBVEFfRlBDSV9CQVI1KTsNCj4+ICsJLyogRW5hYmxpbmcg
TFBNIGNhcGFiaWxpdGllcyB0aHJvdWdoIEJhY2tkb29yIFByb2dyYW1taW5nICovDQo+PiArCXZh
bCA9IHJlYWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArDQo+VF9TQVRBMF9BSENJ
X0hCQV9DQVBfQktEUik7DQo+PiArCXZhbCB8PSAoVF9TQVRBMF9BSENJX0hCQV9DQVBfQktEUl9Q
QVJUSUFMX1NUX0NBUCB8DQo+PiArCQlUX1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1NMVU1CRVJf
U1RfQ0FQIHwNCj4+ICsJCVRfU0FUQTBfQUhDSV9IQkFfQ0FQX0JLRFJfU0FMUCB8DQo+PiArCQlU
X1NBVEEwX0FIQ0lfSEJBX0NBUF9CS0RSX1NVUFBfUE0pOw0KPj4gKwl3cml0ZWwodmFsLCB0ZWdy
YS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKw0KPj4gK1RfU0FUQTBfQUhDSV9IQkFfQ0FQX0JL
RFIpOw0KPj4gKw0KPj4gKwkvKiBTQVRBIFNlY29uZCBMZXZlbCBDbG9jayBHYXRpbmcgY29uZmln
dXJhdGlvbg0KPj4gKwkgKiBFbmFibGluZyBHYXRpbmcgb2YgVHgvUnggY2xvY2tzIGFuZCBkcml2
aW5nIFBhZCBJRERRIGFuZCBMYW5lDQo+PiArCSAqIElERFEgU2lnbmFscw0KPj4gKwkgKi8NCj4+
ICsJdmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9D
RkdfMzUpOw0KPj4gKwl2YWwgJj0gflRfU0FUQTBfQ0ZHXzM1X0lEUF9JTkRFWF9NQVNLOw0KPj4g
Kwl2YWwgfD0gVF9TQVRBMF9DRkdfMzVfSURQX0lOREVYOw0KPj4gKwl3cml0ZWwodmFsLCB0ZWdy
YS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NGR18zNSk7DQo+PiArDQo+PiAr
CXZhbCA9IFRfU0FUQTBfQUhDSV9JRFAxX0RBVEE7DQo+PiArCXdyaXRlbCh2YWwsIHRlZ3JhLT5z
YXRhX3JlZ3MgKyBTQ0ZHX09GRlNFVCArIFRfU0FUQTBfQUhDSV9JRFAxKTsNCj4+ICsNCj4+ICsJ
dmFsID0gcmVhZGwodGVncmEtPnNhdGFfcmVncyArIFNDRkdfT0ZGU0VUICsgVF9TQVRBMF9DRkdf
UEhZXzEpOw0KPj4gKwl2YWwgfD0gKFRfU0FUQTBfQ0ZHX1BIWV8xX1BBRFNfSUREUV9FTiB8DQo+
PiArCQlUX1NBVEEwX0NGR19QSFlfMV9QQURfUExMX0lERFFfRU4pOw0KPj4gKwl3cml0ZWwodmFs
LCB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NGR19QSFlfMSk7DQo+
PiArDQo+PiArCS8qIEVuYWJsaW5nIElQRlMgQ2xvY2sgR2F0aW5nICovDQo+PiArCXZhbCA9IHJl
YWRsKHRlZ3JhLT5zYXRhX3JlZ3MgKyBTQVRBX0NPTkZJR1VSQVRJT05fMCk7DQo+PiArCXZhbCAm
PSB+U0FUQV9DT05GSUdVUkFUSU9OXzBfQ0xLX09WRVJSSURFOw0KPj4gKwl3cml0ZWwodmFsLCB0
ZWdyYS0+c2F0YV9yZWdzICsgU0FUQV9DT05GSUdVUkFUSU9OXzApOw0KPj4NCj4+IC0Jd3JpdGVs
KDB4MDgwMDAgPDwgVF9TQVRBMF9DRkdfOV9CQVNFX0FERFJFU1NfU0hJRlQsDQo+PiAtCSAgICAg
ICB0ZWdyYS0+c2F0YV9yZWdzICsgU0NGR19PRkZTRVQgKyBUX1NBVEEwX0NGR185KTsNCj4+DQo+
PiAgIAkvKiBVbm1hc2sgU0FUQSBpbnRlcnJ1cHRzICovDQo+Pg0KPj4gQEAgLTI4Niw3ICs0Mzks
MTAgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBhdGFfcG9ydF9pbmZvIGFoY2lfdGVncmFfcG9ydF9p
bmZvDQo+PSB7DQo+PiAgIH07DQo+Pg0KPj4gICBzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2Rldmlj
ZV9pZCB0ZWdyYV9haGNpX29mX21hdGNoW10gPSB7DQo+PiAtCXsgLmNvbXBhdGlibGUgPSAibnZp
ZGlhLHRlZ3JhMTI0LWFoY2kiIH0sDQo+PiArCXsNCj4+ICsJCS5jb21wYXRpYmxlID0gIm52aWRp
YSx0ZWdyYTEyNC1haGNpIiwNCj4+ICsJCS5kYXRhID0gJnRlZ3JhMTI0X2FoY2lfc29jX2RhdGEN
Cj4+ICsJfSwNCj4+ICAgCXt9DQo+PiAgIH07DQo+PiAgIE1PRFVMRV9ERVZJQ0VfVEFCTEUob2Ys
IHRlZ3JhX2FoY2lfb2ZfbWF0Y2gpOyBAQCAtMzAxLDYgKzQ1Nyw3IEBADQo+PiBzdGF0aWMgaW50
IHRlZ3JhX2FoY2lfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikNCj4+ICAgCXN0
cnVjdCB0ZWdyYV9haGNpX3ByaXYgKnRlZ3JhOw0KPj4gICAJc3RydWN0IHJlc291cmNlICpyZXM7
DQo+PiAgIAlpbnQgcmV0Ow0KPj4gKwl1bnNpZ25lZCBpbnQgaTsNCj4NCj5UaGlzIHZhcmlhYmxl
IGRvZXNuJ3Qgc2VlbSB0byBiZSB1c2VkIGhlcmUuDQo+DQpUaGlzIHZhcmlhYmxlIHNob3VsZCBi
ZSBwYXJ0IG9mIHRoZSByZWd1bGF0b3IgcGF0Y2guIFdpbGwgY29ycmVjdCBpdA0KPj4NCj4+ICAg
CWhwcml2ID0gYWhjaV9wbGF0Zm9ybV9nZXRfcmVzb3VyY2VzKHBkZXYpOw0KPj4gICAJaWYgKElT
X0VSUihocHJpdikpDQo+PiBAQCAtMzEzLDYgKzQ3MCw4IEBAIHN0YXRpYyBpbnQgdGVncmFfYWhj
aV9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlDQo+KnBkZXYpDQo+PiAgIAlocHJpdi0+cGxh
dF9kYXRhID0gdGVncmE7DQo+Pg0KPj4gICAJdGVncmEtPnBkZXYgPSBwZGV2Ow0KPj4gKwl0ZWdy
YS0+c29jX2RhdGEgPQ0KPj4gKwkgICAgKHN0cnVjdCB0ZWdyYV9haGNpX3NvYyAqKW9mX2Rldmlj
ZV9nZXRfbWF0Y2hfZGF0YSgmcGRldi0+ZGV2KTsNCj4+DQo+PiAgIAlyZXMgPSBwbGF0Zm9ybV9n
ZXRfcmVzb3VyY2UocGRldiwgSU9SRVNPVVJDRV9NRU0sIDEpOw0KPj4gICAJdGVncmEtPnNhdGFf
cmVncyA9IGRldm1faW9yZW1hcF9yZXNvdXJjZSgmcGRldi0+ZGV2LCByZXMpOw0KPj4NCj4NCj5P
dGhlcndpc2UgbG9va3MgZ29vZCB0byBtZS4NCj4NCj5NaWtrbw0K
--
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox series

Patch

diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index 3a62eb246d80..71850e96e787 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -34,7 +34,8 @@ 
 #define DRV_NAME "tegra-ahci"
 
 #define SATA_CONFIGURATION_0				0x180
-#define SATA_CONFIGURATION_EN_FPCI			BIT(0)
+#define SATA_CONFIGURATION_0_EN_FPCI			BIT(0)
+#define SATA_CONFIGURATION_0_CLK_OVERRIDE			BIT(31)
 
 #define SCFG_OFFSET					0x1000
 
@@ -45,17 +46,55 @@ 
 #define T_SATA0_CFG_1_SERR				BIT(8)
 
 #define T_SATA0_CFG_9					0x24
-#define T_SATA0_CFG_9_BASE_ADDRESS_SHIFT		13
+#define T_SATA0_CFG_9_BASE_ADDRESS			0x40020000
 
 #define SATA_FPCI_BAR5					0x94
-#define SATA_FPCI_BAR5_START_SHIFT			4
+#define SATA_FPCI_BAR5_START_MASK			(0xfffffff << 4)
+#define SATA_FPCI_BAR5_START				(0x0040020 << 4)
+#define SATA_FPCI_BAR5_ACCESS_TYPE			(0x1)
 
 #define SATA_INTR_MASK					0x188
 #define SATA_INTR_MASK_IP_INT_MASK			BIT(16)
 
+#define T_SATA0_CFG_35					0x94
+#define T_SATA0_CFG_35_IDP_INDEX_MASK			(0x7ff << 2)
+#define T_SATA0_CFG_35_IDP_INDEX			(0x2a << 2)
+
+#define T_SATA0_AHCI_IDP1				0x98
+#define T_SATA0_AHCI_IDP1_DATA				(0x400040)
+
+#define T_SATA0_CFG_PHY_1				0x12c
+#define T_SATA0_CFG_PHY_1_PADS_IDDQ_EN			BIT(23)
+#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
+
+#define T_SATA0_NVOOB                                   0x114
+#define T_SATA0_NVOOB_COMMA_CNT_MASK                    (0xff << 16)
+#define T_SATA0_NVOOB_COMMA_CNT                         (0x07 << 16)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK          (0x3 << 24)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 24)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK        (0x3 << 26)
+#define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH             (0x3 << 26)
+
+#define T_SATA_CFG_PHY_0                                0x120
+#define T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD     BIT(11)
+#define T_SATA_CFG_PHY_0_MASK_SQUELCH                   BIT(24)
+
+#define T_SATA0_CFG2NVOOB_2				0x134
+#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK	(0x1ff << 18)
+#define T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW	(0xc << 18)
+
 #define T_SATA0_AHCI_HBA_CAP_BKDR			0x300
+#define T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP	BIT(13)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP	BIT(14)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP			BIT(26)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM		BIT(17)
+#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ			BIT(30)
 
 #define T_SATA0_BKDOOR_CC				0x4a4
+#define T_SATA0_BKDOOR_CC_CLASS_CODE_MASK		(0xffff << 16)
+#define T_SATA0_BKDOOR_CC_CLASS_CODE			(0x0106 << 16)
+#define T_SATA0_BKDOOR_CC_PROG_IF_MASK			(0xff << 8)
+#define T_SATA0_BKDOOR_CC_PROG_IF			(0x01 << 8)
 
 #define T_SATA0_CFG_SATA				0x54c
 #define T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN		BIT(12)
@@ -82,6 +121,27 @@ 
 #define T_SATA0_CHX_PHY_CTRL11				0x6d0
 #define T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ		(0x2800 << 16)
 
+#define T_SATA0_CHX_PHY_CTRL17_0			0x6e8
+#define T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1	0x55010000
+#define T_SATA0_CHX_PHY_CTRL18_0			0x6ec
+#define T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2	0x55010000
+#define T_SATA0_CHX_PHY_CTRL20_0			0x6f4
+#define T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1	0x1
+#define T_SATA0_CHX_PHY_CTRL21_0			0x6f8
+#define T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2	0x1
+
+/* AUX Registers */
+#define SATA_AUX_MISC_CNTL_1_0				0x8
+#define SATA_AUX_MISC_CNTL_1_0_DEVSLP_OVERRIDE		BIT(17)
+#define SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT		BIT(13)
+#define SATA_AUX_MISC_CNTL_1_0_DESO_SUPPORT		BIT(15)
+
+#define SATA_AUX_RX_STAT_INT_0				0xc
+#define SATA_AUX_RX_STAT_INT_0_SATA_DEVSLP		BIT(7)
+
+#define SATA_AUX_SPARE_CFG0_0				0x18
+#define SATA_AUX_SPARE_CFG0_0_MDAT_TIMER_AFTER_PG_VALID	BIT(14)
+
 #define FUSE_SATA_CALIB					0x124
 #define FUSE_SATA_CALIB_MASK				0x3
 
@@ -99,6 +159,14 @@  static const struct sata_pad_calibration tegra124_pad_calibration[] = {
 	{0x14, 0x0e, 0x1a, 0x0e},
 };
 
+struct tegra_ahci_ops {
+	int (*init)(struct ahci_host_priv *hpriv);
+};
+
+struct tegra_ahci_soc {
+	struct tegra_ahci_ops	ops;
+};
+
 struct tegra_ahci_priv {
 	struct platform_device	   *pdev;
 	void __iomem		   *sata_regs;
@@ -108,6 +176,57 @@  struct tegra_ahci_priv {
 	/* Needs special handling, cannot use ahci_platform */
 	struct clk		   *sata_clk;
 	struct regulator_bulk_data supplies[5];
+	struct tegra_ahci_soc	   *soc_data;
+};
+
+static int tegra124_ahci_init(struct ahci_host_priv *hpriv)
+{
+	struct tegra_ahci_priv *tegra = hpriv->plat_data;
+	struct sata_pad_calibration calib;
+	int ret;
+	u32 val;
+
+	/* Pad calibration */
+	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
+	if (ret)
+		return ret;
+
+	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
+
+	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
+
+	val = readl(tegra->sata_regs +
+		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
+	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
+	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
+	val |= calib.gen1_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
+	val |= calib.gen1_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
+	writel(val, tegra->sata_regs + SCFG_OFFSET +
+	       T_SATA0_CHX_PHY_CTRL1_GEN1);
+
+	val = readl(tegra->sata_regs +
+		    SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
+	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
+	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
+	val |= calib.gen2_tx_amp << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
+	val |= calib.gen2_tx_peak << T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
+	writel(val, tegra->sata_regs + SCFG_OFFSET +
+	       T_SATA0_CHX_PHY_CTRL1_GEN2);
+
+	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
+	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
+	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
+	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
+
+	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
+
+	return 0;
+}
+
+static const struct tegra_ahci_soc tegra124_ahci_soc_data = {
+	.ops = {
+		.init = tegra124_ahci_init,
+	},
 };
 
 static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
@@ -145,7 +264,6 @@  static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
 
 disable_regulators:
 	regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies);
-
 	return ret;
 }
 
@@ -169,8 +287,7 @@  static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
 {
 	struct tegra_ahci_priv *tegra = hpriv->plat_data;
 	int ret;
-	unsigned int val;
-	struct sata_pad_calibration calib;
+	u32 val;
 
 	ret = tegra_ahci_power_on(hpriv);
 	if (ret) {
@@ -179,78 +296,114 @@  static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
 		return ret;
 	}
 
+	/*
+	 * Program the following SATA IPFS registers
+	 * to allow SW accesses to SATA's MMIO register range.
+	 */
+	val = readl(tegra->sata_regs + SATA_FPCI_BAR5);
+	val &= ~(SATA_FPCI_BAR5_START_MASK | SATA_FPCI_BAR5_ACCESS_TYPE);
+	val |= SATA_FPCI_BAR5_START | SATA_FPCI_BAR5_ACCESS_TYPE;
+	writel(val, tegra->sata_regs + SATA_FPCI_BAR5);
+
+	/* Program the following SATA IPFS register to enable the SATA */
 	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
-	val |= SATA_CONFIGURATION_EN_FPCI;
+	val |= SATA_CONFIGURATION_0_EN_FPCI;
 	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
 
-	/* Pad calibration */
-
-	ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
-	if (ret) {
-		dev_err(&tegra->pdev->dev,
-			"failed to read calibration fuse: %d\n", ret);
-		return ret;
-	}
-
-	calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
-
-	writel(BIT(0), tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
-
-	val = readl(tegra->sata_regs +
-		SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN1);
-	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_MASK;
-	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_MASK;
-	val |= calib.gen1_tx_amp <<
-			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
-	val |= calib.gen1_tx_peak <<
-			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
-	writel(val, tegra->sata_regs + SCFG_OFFSET +
-		T_SATA0_CHX_PHY_CTRL1_GEN1);
-
-	val = readl(tegra->sata_regs +
-			SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL1_GEN2);
-	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_AMP_MASK;
-	val &= ~T_SATA0_CHX_PHY_CTRL1_GEN2_TX_PEAK_MASK;
-	val |= calib.gen2_tx_amp <<
-			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_AMP_SHIFT;
-	val |= calib.gen2_tx_peak <<
-			T_SATA0_CHX_PHY_CTRL1_GEN1_TX_PEAK_SHIFT;
-	writel(val, tegra->sata_regs + SCFG_OFFSET +
-		T_SATA0_CHX_PHY_CTRL1_GEN2);
-
-	writel(T_SATA0_CHX_PHY_CTRL11_GEN2_RX_EQ,
-		tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL11);
-	writel(T_SATA0_CHX_PHY_CTRL2_CDR_CNTL_GEN1,
-		tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL2);
-
-	writel(0, tegra->sata_regs + SCFG_OFFSET + T_SATA0_INDEX);
-
-	/* Program controller device ID */
+	/* Electrical settings for better link stability */
+	val = T_SATA0_CHX_PHY_CTRL17_0_RX_EQ_CTRL_L_GEN1;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL17_0);
+	val = T_SATA0_CHX_PHY_CTRL18_0_RX_EQ_CTRL_L_GEN2;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL18_0);
+	val = T_SATA0_CHX_PHY_CTRL20_0_RX_EQ_CTRL_H_GEN1;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL20_0);
+	val = T_SATA0_CHX_PHY_CTRL21_0_RX_EQ_CTRL_H_GEN2;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CHX_PHY_CTRL21_0);
+
+	/* For SQUELCH Filter & Gen3 drive getting detected as Gen1 drive */
+
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
+	val |= T_SATA_CFG_PHY_0_MASK_SQUELCH;
+	val &= ~T_SATA_CFG_PHY_0_USE_7BIT_ALIGN_DET_FOR_SPD;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
+
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
+	val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK |
+		 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
+		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
+	val |= (T_SATA0_NVOOB_COMMA_CNT |
+		T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
+		T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
+
+	/*
+	 * Change CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW from 83.3 ns to 58.8ns
+	 */
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
+	val &= ~T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW_MASK;
+	val |= T_SATA0_CFG2NVOOB_2_COMWAKE_IDLE_CNT_LOW;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG2NVOOB_2);
+
+	if (tegra->soc_data->ops.init)
+		tegra->soc_data->ops.init(hpriv);
+
+	/*
+	 * Program the following SATA configuration registers
+	 * to initialize SATA
+	 */
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
+	val |= (T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
+		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR);
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
+	val = T_SATA0_CFG_9_BASE_ADDRESS;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
 
+	/* Program Class Code and Programming interface for SATA */
 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
 	val |= T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
 
-	writel(0x01060100, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
+	val &=
+	    ~(T_SATA0_BKDOOR_CC_CLASS_CODE_MASK |
+	      T_SATA0_BKDOOR_CC_PROG_IF_MASK);
+	val |= T_SATA0_BKDOOR_CC_CLASS_CODE | T_SATA0_BKDOOR_CC_PROG_IF;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_BKDOOR_CC);
 
 	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
 	val &= ~T_SATA0_CFG_SATA_BACKDOOR_PROG_IF_EN;
 	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_SATA);
 
-	/* Enable IO & memory access, bus master mode */
-
-	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
-	val |= T_SATA0_CFG_1_IO_SPACE | T_SATA0_CFG_1_MEMORY_SPACE |
-		T_SATA0_CFG_1_BUS_MASTER | T_SATA0_CFG_1_SERR;
-	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_1);
-
-	/* Program SATA MMIO */
-
-	writel(0x10000 << SATA_FPCI_BAR5_START_SHIFT,
-	       tegra->sata_regs + SATA_FPCI_BAR5);
+	/* Enabling LPM capabilities through Backdoor Programming */
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
+	val |= (T_SATA0_AHCI_HBA_CAP_BKDR_PARTIAL_ST_CAP |
+		T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP |
+		T_SATA0_AHCI_HBA_CAP_BKDR_SALP |
+		T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM);
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_HBA_CAP_BKDR);
+
+	/* SATA Second Level Clock Gating configuration
+	 * Enabling Gating of Tx/Rx clocks and driving Pad IDDQ and Lane
+	 * IDDQ Signals
+	 */
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
+	val &= ~T_SATA0_CFG_35_IDP_INDEX_MASK;
+	val |= T_SATA0_CFG_35_IDP_INDEX;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_35);
+
+	val = T_SATA0_AHCI_IDP1_DATA;
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_AHCI_IDP1);
+
+	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
+	val |= (T_SATA0_CFG_PHY_1_PADS_IDDQ_EN |
+		T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN);
+	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_PHY_1);
+
+	/* Enabling IPFS Clock Gating */
+	val = readl(tegra->sata_regs + SATA_CONFIGURATION_0);
+	val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE;
+	writel(val, tegra->sata_regs + SATA_CONFIGURATION_0);
 
-	writel(0x08000 << T_SATA0_CFG_9_BASE_ADDRESS_SHIFT,
-	       tegra->sata_regs + SCFG_OFFSET + T_SATA0_CFG_9);
 
 	/* Unmask SATA interrupts */
 
@@ -286,7 +439,10 @@  static const struct ata_port_info ahci_tegra_port_info = {
 };
 
 static const struct of_device_id tegra_ahci_of_match[] = {
-	{ .compatible = "nvidia,tegra124-ahci" },
+	{
+		.compatible = "nvidia,tegra124-ahci",
+		.data = &tegra124_ahci_soc_data
+	},
 	{}
 };
 MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
@@ -301,6 +457,7 @@  static int tegra_ahci_probe(struct platform_device *pdev)
 	struct tegra_ahci_priv *tegra;
 	struct resource *res;
 	int ret;
+	unsigned int i;
 
 	hpriv = ahci_platform_get_resources(pdev);
 	if (IS_ERR(hpriv))
@@ -313,6 +470,8 @@  static int tegra_ahci_probe(struct platform_device *pdev)
 	hpriv->plat_data = tegra;
 
 	tegra->pdev = pdev;
+	tegra->soc_data =
+	    (struct tegra_ahci_soc *)of_device_get_match_data(&pdev->dev);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	tegra->sata_regs = devm_ioremap_resource(&pdev->dev, res);