mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									d843419d29
								
							
						
					
					
						commit
						868ed7311c
					
				
					 1 changed files with 47 additions and 13 deletions
				
			
		| 
						 | 
					@ -59,8 +59,6 @@
 | 
				
			||||||
#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
 | 
					#define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN		BIT(22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define T_SATA0_NVOOB                                   0x114
 | 
					#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_MASK          (0x3 << 24)
 | 
				
			||||||
#define T_SATA0_NVOOB_SQUELCH_FILTER_MODE               (0x1 << 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_MASK        (0x3 << 26)
 | 
				
			||||||
| 
						 | 
					@ -154,11 +152,18 @@ struct tegra_ahci_ops {
 | 
				
			||||||
	int (*init)(struct ahci_host_priv *hpriv);
 | 
						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 {
 | 
					struct tegra_ahci_soc {
 | 
				
			||||||
	const char *const		*supply_names;
 | 
						const char *const		*supply_names;
 | 
				
			||||||
	u32				num_supplies;
 | 
						u32				num_supplies;
 | 
				
			||||||
	bool				supports_devslp;
 | 
						bool				supports_devslp;
 | 
				
			||||||
 | 
						bool				has_sata_oob_rst;
 | 
				
			||||||
	const struct tegra_ahci_ops	*ops;
 | 
						const struct tegra_ahci_ops	*ops;
 | 
				
			||||||
 | 
						const struct tegra_ahci_regs	*regs;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct tegra_ahci_priv {
 | 
					struct tegra_ahci_priv {
 | 
				
			||||||
| 
						 | 
					@ -240,11 +245,13 @@ static int tegra_ahci_power_on(struct ahci_host_priv *hpriv)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
 | 
						if (!tegra->pdev->dev.pm_domain) {
 | 
				
			||||||
						tegra->sata_clk,
 | 
							ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA,
 | 
				
			||||||
						tegra->sata_rst);
 | 
												tegra->sata_clk,
 | 
				
			||||||
	if (ret)
 | 
												tegra->sata_rst);
 | 
				
			||||||
		goto disable_regulators;
 | 
							if (ret)
 | 
				
			||||||
 | 
								goto disable_regulators;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	reset_control_assert(tegra->sata_oob_rst);
 | 
						reset_control_assert(tegra->sata_oob_rst);
 | 
				
			||||||
	reset_control_assert(tegra->sata_cold_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);
 | 
						writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
 | 
						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_LENGTH_MASK |
 | 
				
			||||||
		 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_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_LENGTH |
 | 
				
			||||||
		T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
 | 
							T_SATA0_NVOOB_SQUELCH_FILTER_MODE);
 | 
				
			||||||
	writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB);
 | 
						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,
 | 
						.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 = {
 | 
					static const struct tegra_ahci_soc tegra124_ahci_soc = {
 | 
				
			||||||
	.supply_names = tegra124_supply_names,
 | 
						.supply_names = tegra124_supply_names,
 | 
				
			||||||
	.num_supplies = ARRAY_SIZE(tegra124_supply_names),
 | 
						.num_supplies = ARRAY_SIZE(tegra124_supply_names),
 | 
				
			||||||
	.supports_devslp = false,
 | 
						.supports_devslp = false,
 | 
				
			||||||
 | 
						.has_sata_oob_rst = true,
 | 
				
			||||||
	.ops = &tegra124_ahci_ops,
 | 
						.ops = &tegra124_ahci_ops,
 | 
				
			||||||
 | 
						.regs = &tegra124_ahci_regs,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct tegra_ahci_soc tegra210_ahci_soc = {
 | 
					static const struct tegra_ahci_soc tegra210_ahci_soc = {
 | 
				
			||||||
	.supports_devslp = false,
 | 
						.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[] = {
 | 
					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",
 | 
							.compatible = "nvidia,tegra210-ahci",
 | 
				
			||||||
		.data = &tegra210_ahci_soc
 | 
							.data = &tegra210_ahci_soc
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							.compatible = "nvidia,tegra186-ahci",
 | 
				
			||||||
 | 
							.data = &tegra186_ahci_soc
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
MODULE_DEVICE_TABLE(of, tegra_ahci_of_match);
 | 
					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);
 | 
							return PTR_ERR(tegra->sata_rst);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, "sata-oob");
 | 
						if (tegra->soc->has_sata_oob_rst) {
 | 
				
			||||||
	if (IS_ERR(tegra->sata_oob_rst)) {
 | 
							tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev,
 | 
				
			||||||
		dev_err(&pdev->dev, "Failed to get sata-oob reset\n");
 | 
												     "sata-oob");
 | 
				
			||||||
		return PTR_ERR(tegra->sata_oob_rst);
 | 
							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");
 | 
						tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue