Merge branch 'akpm' (patches from Andrew)
[linux-2.6-microblaze.git] / drivers / ata / ahci_tegra.c
index cb55ebc..4fb94db 100644 (file)
@@ -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);
@@ -261,7 +268,8 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
 disable_power:
        clk_disable_unprepare(tegra->sata_clk);
 
-       tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+       if (!tegra->pdev->dev.pm_domain)
+               tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
 
 disable_regulators:
        regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
@@ -280,7 +288,8 @@ static void tegra_ahci_power_off(struct ahci_host_priv *hpriv)
        reset_control_assert(tegra->sata_cold_rst);
 
        clk_disable_unprepare(tegra->sata_clk);
-       tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
+       if (!tegra->pdev->dev.pm_domain)
+               tegra_powergate_power_off(TEGRA_POWERGATE_SATA);
 
        regulator_bulk_disable(tegra->soc->num_supplies, tegra->supplies);
 }
@@ -330,10 +339,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 +458,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 +498,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 +551,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");