summaryrefslogtreecommitdiff
path: root/drivers/ata
diff options
context:
space:
mode:
authorSowjanya Komatineni <skomatineni@nvidia.com>2021-04-07 04:25:31 +0300
committerJens Axboe <axboe@kernel.dk>2021-04-07 19:05:03 +0300
commit868ed7311cd81ef2fffa2cd36e72c44f226b0085 (patch)
treec6d621e165e1c8fd743c471983e3afae51e844f3 /drivers/ata
parentd843419d295f4d1cc8c24a0c7725785168675b34 (diff)
downloadlinux-868ed7311cd81ef2fffa2cd36e72c44f226b0085.tar.xz
ata: ahci_tegra: Add AHCI support for Tegra186
This patch adds support for AHCI-compliant Serial ATA controller on Tegra186 SoC. Tegra186 does not have sata-oob reset. Tegra186 SATA_NVOOB register filed COMMA_CNT position and width are different compared to Tegra210 and prior. So, this patch adds a flag has_sata_oob_rst and tegra_ahci_regs to SoC specific strcuture tegra_ahci_soc and updated their implementation accordingly. Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com> Acked-by: Thierry Reding <treding@nvidia.com> Link: https://lore.kernel.org/r/1617758731-12380-4-git-send-email-skomatineni@nvidia.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/ahci_tegra.c60
1 files changed, 47 insertions, 13 deletions
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
index cb55ebc1725b..56612af16db0 100644
--- a/drivers/ata/ahci_tegra.c
+++ b/drivers/ata/ahci_tegra.c
@@ -59,8 +59,6 @@
#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)
@@ -154,11 +152,18 @@ struct tegra_ahci_ops {
int (*init)(struct ahci_host_priv *hpriv);
};
+struct tegra_ahci_regs {
+ unsigned int nvoob_comma_cnt_mask;
+ unsigned int nvoob_comma_cnt_val;
+};
+
struct tegra_ahci_soc {
const char *const *supply_names;
u32 num_supplies;
bool supports_devslp;
+ bool has_sata_oob_rst;
const struct tegra_ahci_ops *ops;
+ const struct tegra_ahci_regs *regs;
};
struct tegra_ahci_priv {
@@ -240,11 +245,13 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
if (ret)
return ret;
- ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
- tegra->sata_clk,
- tegra->sata_rst);
- if (ret)
- goto disable_regulators;
+ if (!tegra->pdev->dev.pm_domain) {
+ ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
+ tegra->sata_clk,
+ tegra->sata_rst);
+ if (ret)
+ goto disable_regulators;
+ }
reset_control_assert(tegra->sata_oob_rst);
reset_control_assert(tegra->sata_cold_rst);
@@ -330,10 +337,10 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
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 |
+ val &= ~(tegra->soc->regs->nvoob_comma_cnt_mask |
T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK |
T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK);
- val |= (T_SATA0_NVOOB_COMMA_CNT |
+ val |= (tegra->soc->regs->nvoob_comma_cnt_val |
T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH |
T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
@@ -449,15 +456,35 @@ static const struct tegra_ahci_ops tegra124_ahci_ops = {
.init = tegra124_ahci_init,
};
+static const struct tegra_ahci_regs tegra124_ahci_regs = {
+ .nvoob_comma_cnt_mask = GENMASK(30, 28),
+ .nvoob_comma_cnt_val = (7 << 28),
+};
+
static const struct tegra_ahci_soc tegra124_ahci_soc = {
.supply_names = tegra124_supply_names,
.num_supplies = ARRAY_SIZE(tegra124_supply_names),
.supports_devslp = false,
+ .has_sata_oob_rst = true,
.ops = &tegra124_ahci_ops,
+ .regs = &tegra124_ahci_regs,
};
static const struct tegra_ahci_soc tegra210_ahci_soc = {
.supports_devslp = false,
+ .has_sata_oob_rst = true,
+ .regs = &tegra124_ahci_regs,
+};
+
+static const struct tegra_ahci_regs tegra186_ahci_regs = {
+ .nvoob_comma_cnt_mask = GENMASK(23, 16),
+ .nvoob_comma_cnt_val = (7 << 16),
+};
+
+static const struct tegra_ahci_soc tegra186_ahci_soc = {
+ .supports_devslp = false,
+ .has_sata_oob_rst = false,
+ .regs = &tegra186_ahci_regs,
};
static const struct of_device_id tegra_ahci_of_match[] = {
@@ -469,6 +496,10 @@ static const struct of_device_id tegra_ahci_of_match[] = {
.compatible = "nvidia,tegra210-ahci",
.data = &tegra210_ahci_soc
},
+ {
+ .compatible = "nvidia,tegra186-ahci",
+ .data = &tegra186_ahci_soc
+ },
{}
};
MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
@@ -518,10 +549,13 @@ static int tegra_ahci_probe(struct platform_device *pdev)
return PTR_ERR(tegra->sata_rst);
}
- tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, "sata-oob");
- if (IS_ERR(tegra->sata_oob_rst)) {
- dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
- return PTR_ERR(tegra->sata_oob_rst);
+ if (tegra->soc->has_sata_oob_rst) {
+ tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev,
+ "sata-oob");
+ if (IS_ERR(tegra->sata_oob_rst)) {
+ dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
+ return PTR_ERR(tegra->sata_oob_rst);
+ }
}
tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");