diff --git a/debian/changelog b/debian/changelog index 12bf9913a..6da2617c5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,12 @@ linux (4.16-1~exp2) UNRELEASED; urgency=medium + [ Ben Hutchings ] * aufs: gen-patch: Fix Subject generation to skip SPDX-License-Identifier * aufs: Update support patchset to aufs4.16-20180409 (no functional change) + [ Vagrant Cascadian ] + * [arm64] Add patches to support SATA on Tegra210/Jetson-TX1. + -- Ben Hutchings Sun, 08 Apr 2018 19:03:49 +0100 linux (4.16-1~exp1) experimental; urgency=medium diff --git a/debian/patches/features/arm64/tegra210-sata/0001-ata-ahci_tegra-Update-initialization-sequence.patch b/debian/patches/features/arm64/tegra210-sata/0001-ata-ahci_tegra-Update-initialization-sequence.patch new file mode 100644 index 000000000..aa78522ac --- /dev/null +++ b/debian/patches/features/arm64/tegra210-sata/0001-ata-ahci_tegra-Update-initialization-sequence.patch @@ -0,0 +1,399 @@ +From 56337b5576074ece867054b1ec231017a1a0a6b8 Mon Sep 17 00:00:00 2001 +From: Preetham Ramchandra +Date: Mon, 12 Mar 2018 17:10:33 +0530 +Subject: [PATCH 1/7] ata: ahci_tegra: Update initialization sequence + +Update the controller initialization sequence and move Tegra124 +specifics to tegra124_ahci_init. + +Signed-off-by: Preetham Chandru R +Acked-by: Thierry Reding +Signed-off-by: Tejun Heo +--- + drivers/ata/ahci_tegra.c | 288 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 224 insertions(+), 64 deletions(-) + +diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c +index 3a62eb246d80..055c65082a93 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 { ++ const struct tegra_ahci_ops *ops; ++}; ++ + struct tegra_ahci_priv { + struct platform_device *pdev; + void __iomem *sata_regs; +@@ -108,8 +176,53 @@ struct tegra_ahci_priv { + /* Needs special handling, cannot use ahci_platform */ + struct clk *sata_clk; + struct regulator_bulk_data supplies[5]; ++ const struct tegra_ahci_soc *soc; + }; + ++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 int tegra_ahci_power_on(struct ahci_host_priv *hpriv) + { + struct tegra_ahci_priv *tegra = hpriv->plat_data; +@@ -169,8 +282,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 +291,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->ops && tegra->soc->ops->init) ++ tegra->soc->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 */ + +@@ -285,8 +433,19 @@ static const struct ata_port_info ahci_tegra_port_info = { + .port_ops = &ahci_tegra_port_ops, + }; + ++static const struct tegra_ahci_ops tegra124_ahci_ops = { ++ .init = tegra124_ahci_init, ++}; ++ ++static const struct tegra_ahci_soc tegra124_ahci_soc = { ++ .ops = &tegra124_ahci_ops, ++}; ++ + static const struct of_device_id tegra_ahci_of_match[] = { +- { .compatible = "nvidia,tegra124-ahci" }, ++ { ++ .compatible = "nvidia,tegra124-ahci", ++ .data = &tegra124_ahci_soc ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); +@@ -313,6 +472,7 @@ static int tegra_ahci_probe(struct platform_device *pdev) + hpriv->plat_data = tegra; + + tegra->pdev = pdev; ++ tegra->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); +-- +2.11.0 + diff --git a/debian/patches/features/arm64/tegra210-sata/0002-ata-ahci_tegra-initialize-regulators-from-soc-struct.patch b/debian/patches/features/arm64/tegra210-sata/0002-ata-ahci_tegra-initialize-regulators-from-soc-struct.patch new file mode 100644 index 000000000..756f0528c --- /dev/null +++ b/debian/patches/features/arm64/tegra210-sata/0002-ata-ahci_tegra-initialize-regulators-from-soc-struct.patch @@ -0,0 +1,117 @@ +From 43ee827b562b092f594375945aec9178f9b5cca4 Mon Sep 17 00:00:00 2001 +From: Preetham Ramchandra +Date: Mon, 12 Mar 2018 17:10:34 +0530 +Subject: [PATCH 2/7] ata: ahci_tegra: initialize regulators from soc struct + +Get the regulator names to be initialized from soc structure +and initialize them. + +Signed-off-by: Preetham Chandru R +Acked-by: Thierry Reding +Signed-off-by: Tejun Heo +--- + drivers/ata/ahci_tegra.c | 33 +++++++++++++++++++++++---------- + 1 file changed, 23 insertions(+), 10 deletions(-) + +diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c +index 055c65082a93..547a6f93922c 100644 +--- a/drivers/ata/ahci_tegra.c ++++ b/drivers/ata/ahci_tegra.c +@@ -164,6 +164,8 @@ struct tegra_ahci_ops { + }; + + struct tegra_ahci_soc { ++ const char *const *supply_names; ++ u32 num_supplies; + const struct tegra_ahci_ops *ops; + }; + +@@ -175,7 +177,7 @@ struct tegra_ahci_priv { + struct reset_control *sata_cold_rst; + /* Needs special handling, cannot use ahci_platform */ + struct clk *sata_clk; +- struct regulator_bulk_data supplies[5]; ++ struct regulator_bulk_data *supplies; + const struct tegra_ahci_soc *soc; + }; + +@@ -228,7 +230,7 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv) + struct tegra_ahci_priv *tegra = hpriv->plat_data; + int ret; + +- ret = regulator_bulk_enable(ARRAY_SIZE(tegra->supplies), ++ ret = regulator_bulk_enable(tegra->soc->num_supplies, + tegra->supplies); + if (ret) + return ret; +@@ -257,7 +259,7 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv) + tegra_powergate_power_off(TEGRA_POWERGATE_SATA); + + disable_regulators: +- regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies); ++ regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); + + return ret; + } +@@ -275,7 +277,7 @@ static void tegra_ahci_power_off(struct ahci_host_priv *hpriv) + clk_disable_unprepare(tegra->sata_clk); + tegra_powergate_power_off(TEGRA_POWERGATE_SATA); + +- regulator_bulk_disable(ARRAY_SIZE(tegra->supplies), tegra->supplies); ++ regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies); + } + + static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) +@@ -433,11 +435,17 @@ static const struct ata_port_info ahci_tegra_port_info = { + .port_ops = &ahci_tegra_port_ops, + }; + ++static const char *const tegra124_supply_names[] = { ++ "avdd", "hvdd", "vddio", "target-5v", "target-12v" ++}; ++ + static const struct tegra_ahci_ops tegra124_ahci_ops = { + .init = tegra124_ahci_init, + }; + + static const struct tegra_ahci_soc tegra124_ahci_soc = { ++ .supply_names = tegra124_supply_names, ++ .num_supplies = ARRAY_SIZE(tegra124_supply_names), + .ops = &tegra124_ahci_ops, + }; + +@@ -460,6 +468,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)) +@@ -503,13 +512,17 @@ static int tegra_ahci_probe(struct platform_device *pdev) + return PTR_ERR(tegra->sata_clk); + } + +- tegra->supplies[0].supply = "avdd"; +- tegra->supplies[1].supply = "hvdd"; +- tegra->supplies[2].supply = "vddio"; +- tegra->supplies[3].supply = "target-5v"; +- tegra->supplies[4].supply = "target-12v"; ++ tegra->supplies = devm_kcalloc(&pdev->dev, ++ tegra->soc->num_supplies, ++ sizeof(*tegra->supplies), GFP_KERNEL); ++ if (!tegra->supplies) ++ return -ENOMEM; ++ ++ for (i = 0; i < tegra->soc->num_supplies; i++) ++ tegra->supplies[i].supply = tegra->soc->supply_names[i]; + +- ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(tegra->supplies), ++ ret = devm_regulator_bulk_get(&pdev->dev, ++ tegra->soc->num_supplies, + tegra->supplies); + if (ret) { + dev_err(&pdev->dev, "Failed to get regulators\n"); +-- +2.11.0 + diff --git a/debian/patches/features/arm64/tegra210-sata/0003-ata-ahci_tegra-disable-devslp-for-Tegra124.patch b/debian/patches/features/arm64/tegra210-sata/0003-ata-ahci_tegra-disable-devslp-for-Tegra124.patch new file mode 100644 index 000000000..5bf7f52a6 --- /dev/null +++ b/debian/patches/features/arm64/tegra210-sata/0003-ata-ahci_tegra-disable-devslp-for-Tegra124.patch @@ -0,0 +1,88 @@ +From 502717ccf7720e785fdc1c9202d1b3930fd08038 Mon Sep 17 00:00:00 2001 +From: Preetham Ramchandra +Date: Mon, 12 Mar 2018 17:10:35 +0530 +Subject: [PATCH 3/7] ata: ahci_tegra: disable devslp for Tegra124 + +Tegra124 does not support devslp and it should be disabled. + +Signed-off-by: Preetham Chandru R +Acked-by: Thierry Reding +Signed-off-by: Tejun Heo +--- + drivers/ata/ahci_tegra.c | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c +index 547a6f93922c..620cdd16ef2f 100644 +--- a/drivers/ata/ahci_tegra.c ++++ b/drivers/ata/ahci_tegra.c +@@ -166,12 +166,14 @@ struct tegra_ahci_ops { + struct tegra_ahci_soc { + const char *const *supply_names; + u32 num_supplies; ++ bool supports_devslp; + const struct tegra_ahci_ops *ops; + }; + + struct tegra_ahci_priv { + struct platform_device *pdev; + void __iomem *sata_regs; ++ void __iomem *sata_aux_regs; + struct reset_control *sata_rst; + struct reset_control *sata_oob_rst; + struct reset_control *sata_cold_rst; +@@ -181,6 +183,18 @@ struct tegra_ahci_priv { + const struct tegra_ahci_soc *soc; + }; + ++static void tegra_ahci_handle_quirks(struct ahci_host_priv *hpriv) ++{ ++ struct tegra_ahci_priv *tegra = hpriv->plat_data; ++ u32 val; ++ ++ if (tegra->sata_aux_regs && !tegra->soc->supports_devslp) { ++ val = readl(tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0); ++ val &= ~SATA_AUX_MISC_CNTL_1_0_SDS_SUPPORT; ++ writel(val, tegra->sata_aux_regs + SATA_AUX_MISC_CNTL_1_0); ++ } ++} ++ + static int tegra124_ahci_init(struct ahci_host_priv *hpriv) + { + struct tegra_ahci_priv *tegra = hpriv->plat_data; +@@ -401,6 +415,7 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv) + val &= ~SATA_CONFIGURATION_0_CLK_OVERRIDE; + writel(val, tegra->sata_regs + SATA_CONFIGURATION_0); + ++ tegra_ahci_handle_quirks(hpriv); + + /* Unmask SATA interrupts */ + +@@ -446,6 +461,7 @@ static const struct tegra_ahci_ops tegra124_ahci_ops = { + static const struct tegra_ahci_soc tegra124_ahci_soc = { + .supply_names = tegra124_supply_names, + .num_supplies = ARRAY_SIZE(tegra124_supply_names), ++ .supports_devslp = false, + .ops = &tegra124_ahci_ops, + }; + +@@ -488,6 +504,16 @@ static int tegra_ahci_probe(struct platform_device *pdev) + if (IS_ERR(tegra->sata_regs)) + return PTR_ERR(tegra->sata_regs); + ++ /* ++ * AUX registers is optional. ++ */ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ if (res) { ++ tegra->sata_aux_regs = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(tegra->sata_aux_regs)) ++ return PTR_ERR(tegra->sata_aux_regs); ++ } ++ + tegra->sata_rst = devm_reset_control_get(&pdev->dev, "sata"); + if (IS_ERR(tegra->sata_rst)) { + dev_err(&pdev->dev, "Failed to get sata reset\n"); +-- +2.11.0 + diff --git a/debian/patches/features/arm64/tegra210-sata/0004-ata-ahci_tegra-disable-DIPM.patch b/debian/patches/features/arm64/tegra210-sata/0004-ata-ahci_tegra-disable-DIPM.patch new file mode 100644 index 000000000..b15b445af --- /dev/null +++ b/debian/patches/features/arm64/tegra210-sata/0004-ata-ahci_tegra-disable-DIPM.patch @@ -0,0 +1,30 @@ +From 01fbf60b0e6fb9932a26959bbf338b9b5b193592 Mon Sep 17 00:00:00 2001 +From: Preetham Ramchandra +Date: Mon, 12 Mar 2018 17:10:36 +0530 +Subject: [PATCH 4/7] ata: ahci_tegra: disable DIPM + +Tegra does not support DIPM and it should be disabled. + +Signed-off-by: Preetham Chandru R +Acked-by: Thierry Reding +Signed-off-by: Tejun Heo +--- + drivers/ata/ahci_tegra.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c +index 620cdd16ef2f..20c1fccbc669 100644 +--- a/drivers/ata/ahci_tegra.c ++++ b/drivers/ata/ahci_tegra.c +@@ -444,7 +444,7 @@ static struct ata_port_operations ahci_tegra_port_ops = { + }; + + static const struct ata_port_info ahci_tegra_port_info = { +- .flags = AHCI_FLAG_COMMON, ++ .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, + .pio_mask = ATA_PIO4, + .udma_mask = ATA_UDMA6, + .port_ops = &ahci_tegra_port_ops, +-- +2.11.0 + diff --git a/debian/patches/features/arm64/tegra210-sata/0005-ata-ahci_tegra-Add-AHCI-support-for-Tegra210.patch b/debian/patches/features/arm64/tegra210-sata/0005-ata-ahci_tegra-Add-AHCI-support-for-Tegra210.patch new file mode 100644 index 000000000..fe1f15ab6 --- /dev/null +++ b/debian/patches/features/arm64/tegra210-sata/0005-ata-ahci_tegra-Add-AHCI-support-for-Tegra210.patch @@ -0,0 +1,49 @@ +From 294840feefb7fefb49a276544cbd29aac28e5e7d Mon Sep 17 00:00:00 2001 +From: Preetham Ramchandra +Date: Mon, 12 Mar 2018 17:10:37 +0530 +Subject: [PATCH 5/7] ata: ahci_tegra: Add AHCI support for Tegra210 + +Add support for the AHCI-compliant Serial ATA host controller on the +Tegra210 system-on-chip. + +Signed-off-by: Preetham Chandru R +Acked-by: Thierry Reding +Signed-off-by: Tejun Heo +--- + drivers/ata/ahci_tegra.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c +index 20c1fccbc669..64d848409fe2 100644 +--- a/drivers/ata/ahci_tegra.c ++++ b/drivers/ata/ahci_tegra.c +@@ -465,11 +465,19 @@ static const struct tegra_ahci_soc tegra124_ahci_soc = { + .ops = &tegra124_ahci_ops, + }; + ++static const struct tegra_ahci_soc tegra210_ahci_soc = { ++ .supports_devslp = false, ++}; ++ + static const struct of_device_id tegra_ahci_of_match[] = { + { + .compatible = "nvidia,tegra124-ahci", + .data = &tegra124_ahci_soc + }, ++ { ++ .compatible = "nvidia,tegra210-ahci", ++ .data = &tegra210_ahci_soc ++ }, + {} + }; + MODULE_DEVICE_TABLE(of, tegra_ahci_of_match); +@@ -584,5 +592,5 @@ static struct platform_driver tegra_ahci_driver = { + module_platform_driver(tegra_ahci_driver); + + MODULE_AUTHOR("Mikko Perttunen "); +-MODULE_DESCRIPTION("Tegra124 AHCI SATA driver"); ++MODULE_DESCRIPTION("Tegra AHCI SATA driver"); + MODULE_LICENSE("GPL v2"); +-- +2.11.0 + diff --git a/debian/patches/features/arm64/tegra210-sata/0006-arm64-tegra-Add-SATA-node-for-Tegra210.patch b/debian/patches/features/arm64/tegra210-sata/0006-arm64-tegra-Add-SATA-node-for-Tegra210.patch new file mode 100644 index 000000000..58929d17b --- /dev/null +++ b/debian/patches/features/arm64/tegra210-sata/0006-arm64-tegra-Add-SATA-node-for-Tegra210.patch @@ -0,0 +1,43 @@ +From 6cb60ec43fd794319e2d31bfea1f9f88a1b897f7 Mon Sep 17 00:00:00 2001 +From: Preetham Ramchandra +Date: Mon, 12 Mar 2018 17:10:31 +0530 +Subject: [PATCH 6/7] arm64: tegra: Add SATA node for Tegra210 + +Populate the SATA node for Tegra210. + +Signed-off-by: Preetham Ramchandra +Signed-off-by: Thierry Reding +--- + arch/arm64/boot/dts/nvidia/tegra210.dtsi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi +index 9c2402108772..3be920efee82 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi +@@ -798,6 +798,22 @@ + #iommu-cells = <1>; + }; + ++ sata@70020000 { ++ compatible = "nvidia,tegra210-ahci"; ++ reg = <0x0 0x70027000 0x0 0x2000>, /* AHCI */ ++ <0x0 0x70020000 0x0 0x7000>, /* SATA */ ++ <0x0 0x70001100 0x0 0x1000>; /* SATA AUX */ ++ interrupts = ; ++ clocks = <&tegra_car TEGRA210_CLK_SATA>, ++ <&tegra_car TEGRA210_CLK_SATA_OOB>; ++ clock-names = "sata", "sata-oob"; ++ resets = <&tegra_car 124>, ++ <&tegra_car 123>, ++ <&tegra_car 129>; ++ reset-names = "sata", "sata-oob", "sata-cold"; ++ status = "disabled"; ++ }; ++ + hda@70030000 { + compatible = "nvidia,tegra210-hda", "nvidia,tegra30-hda"; + reg = <0x0 0x70030000 0x0 0x10000>; +-- +2.11.0 + diff --git a/debian/patches/features/arm64/tegra210-sata/0007-arm64-tegra-Enable-AHCI-on-Jetson-TX1.patch b/debian/patches/features/arm64/tegra210-sata/0007-arm64-tegra-Enable-AHCI-on-Jetson-TX1.patch new file mode 100644 index 000000000..fab051be6 --- /dev/null +++ b/debian/patches/features/arm64/tegra210-sata/0007-arm64-tegra-Enable-AHCI-on-Jetson-TX1.patch @@ -0,0 +1,32 @@ +From 0f2754cee38fd2bc42f446d299ff0c53815dc5bd Mon Sep 17 00:00:00 2001 +From: Preetham Ramchandra +Date: Mon, 12 Mar 2018 17:10:32 +0530 +Subject: [PATCH 7/7] arm64: tegra: Enable AHCI on Jetson TX1 + +Enable AHCI on Jetson TX1 and add sata phy node. + +Signed-off-by: Preetham Chandru R +Signed-off-by: Thierry Reding +--- + arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +index d67ef4319f3b..9d5a0e6b2ca4 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2597.dtsi +@@ -1325,6 +1325,11 @@ + status = "okay"; + }; + ++ sata@70020000 { ++ status = "okay"; ++ phys = <&{/padctl@7009f000/pads/sata/lanes/sata-0}>; ++ }; ++ + padctl@7009f000 { + status = "okay"; + +-- +2.11.0 + diff --git a/debian/patches/series b/debian/patches/series index f6d043d3e..79e7735db 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -79,6 +79,14 @@ features/armhf/meson8/0003-ARM-dts-meson8-add-the-USB-reset-line.patch features/armhf/meson8/0004-ARM-dts-meson8b-extend-ethernet-controller-descripti.patch features/armhf/meson8/0005-ARM-dts-meson8b-odroidc1-ethernet-support.patch features/armhf/meson8/0006-ARM-dts-meson8b-add-the-I2C-clocks.patch +# Add sata support for Tegra210/Jetson-TX1 from mainline. +features/arm64/tegra210-sata/0001-ata-ahci_tegra-Update-initialization-sequence.patch +features/arm64/tegra210-sata/0002-ata-ahci_tegra-initialize-regulators-from-soc-struct.patch +features/arm64/tegra210-sata/0003-ata-ahci_tegra-disable-devslp-for-Tegra124.patch +features/arm64/tegra210-sata/0004-ata-ahci_tegra-disable-DIPM.patch +features/arm64/tegra210-sata/0005-ata-ahci_tegra-Add-AHCI-support-for-Tegra210.patch +features/arm64/tegra210-sata/0006-arm64-tegra-Add-SATA-node-for-Tegra210.patch +features/arm64/tegra210-sata/0007-arm64-tegra-Enable-AHCI-on-Jetson-TX1.patch # Miscellaneous bug fixes bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch