Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Sowjanya Komatineni and committed by
Jens Axboe
868ed731 d843419d

+47 -13
+47 -13
drivers/ata/ahci_tegra.c
··· 59 59 #define T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN BIT(22) 60 60 61 61 #define T_SATA0_NVOOB 0x114 62 - #define T_SATA0_NVOOB_COMMA_CNT_MASK (0xff << 16) 63 - #define T_SATA0_NVOOB_COMMA_CNT (0x07 << 16) 64 62 #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK (0x3 << 24) 65 63 #define T_SATA0_NVOOB_SQUELCH_FILTER_MODE (0x1 << 24) 66 64 #define T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK (0x3 << 26) ··· 152 154 int (*init)(struct ahci_host_priv *hpriv); 153 155 }; 154 156 157 + struct tegra_ahci_regs { 158 + unsigned int nvoob_comma_cnt_mask; 159 + unsigned int nvoob_comma_cnt_val; 160 + }; 161 + 155 162 struct tegra_ahci_soc { 156 163 const char *const *supply_names; 157 164 u32 num_supplies; 158 165 bool supports_devslp; 166 + bool has_sata_oob_rst; 159 167 const struct tegra_ahci_ops *ops; 168 + const struct tegra_ahci_regs *regs; 160 169 }; 161 170 162 171 struct tegra_ahci_priv { ··· 245 240 if (ret) 246 241 return ret; 247 242 248 - ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA, 249 - tegra->sata_clk, 250 - tegra->sata_rst); 251 - if (ret) 252 - goto disable_regulators; 243 + if (!tegra->pdev->dev.pm_domain) { 244 + ret = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_SATA, 245 + tegra->sata_clk, 246 + tegra->sata_rst); 247 + if (ret) 248 + goto disable_regulators; 249 + } 253 250 254 251 reset_control_assert(tegra->sata_oob_rst); 255 252 reset_control_assert(tegra->sata_cold_rst); ··· 337 330 writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA_CFG_PHY_0); 338 331 339 332 val = readl(tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); 340 - val &= ~(T_SATA0_NVOOB_COMMA_CNT_MASK | 333 + val &= ~(tegra->soc->regs->nvoob_comma_cnt_mask | 341 334 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH_MASK | 342 335 T_SATA0_NVOOB_SQUELCH_FILTER_MODE_MASK); 343 - val |= (T_SATA0_NVOOB_COMMA_CNT | 336 + val |= (tegra->soc->regs->nvoob_comma_cnt_val | 344 337 T_SATA0_NVOOB_SQUELCH_FILTER_LENGTH | 345 338 T_SATA0_NVOOB_SQUELCH_FILTER_MODE); 346 339 writel(val, tegra->sata_regs + SCFG_OFFSET + T_SATA0_NVOOB); ··· 456 449 .init = tegra124_ahci_init, 457 450 }; 458 451 452 + static const struct tegra_ahci_regs tegra124_ahci_regs = { 453 + .nvoob_comma_cnt_mask = GENMASK(30, 28), 454 + .nvoob_comma_cnt_val = (7 << 28), 455 + }; 456 + 459 457 static const struct tegra_ahci_soc tegra124_ahci_soc = { 460 458 .supply_names = tegra124_supply_names, 461 459 .num_supplies = ARRAY_SIZE(tegra124_supply_names), 462 460 .supports_devslp = false, 461 + .has_sata_oob_rst = true, 463 462 .ops = &tegra124_ahci_ops, 463 + .regs = &tegra124_ahci_regs, 464 464 }; 465 465 466 466 static const struct tegra_ahci_soc tegra210_ahci_soc = { 467 467 .supports_devslp = false, 468 + .has_sata_oob_rst = true, 469 + .regs = &tegra124_ahci_regs, 470 + }; 471 + 472 + static const struct tegra_ahci_regs tegra186_ahci_regs = { 473 + .nvoob_comma_cnt_mask = GENMASK(23, 16), 474 + .nvoob_comma_cnt_val = (7 << 16), 475 + }; 476 + 477 + static const struct tegra_ahci_soc tegra186_ahci_soc = { 478 + .supports_devslp = false, 479 + .has_sata_oob_rst = false, 480 + .regs = &tegra186_ahci_regs, 468 481 }; 469 482 470 483 static const struct of_device_id tegra_ahci_of_match[] = { ··· 495 468 { 496 469 .compatible = "nvidia,tegra210-ahci", 497 470 .data = &tegra210_ahci_soc 471 + }, 472 + { 473 + .compatible = "nvidia,tegra186-ahci", 474 + .data = &tegra186_ahci_soc 498 475 }, 499 476 {} 500 477 }; ··· 549 518 return PTR_ERR(tegra->sata_rst); 550 519 } 551 520 552 - tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, "sata-oob"); 553 - if (IS_ERR(tegra->sata_oob_rst)) { 554 - dev_err(&pdev->dev, "Failed to get sata-oob reset\n"); 555 - return PTR_ERR(tegra->sata_oob_rst); 521 + if (tegra->soc->has_sata_oob_rst) { 522 + tegra->sata_oob_rst = devm_reset_control_get(&pdev->dev, 523 + "sata-oob"); 524 + if (IS_ERR(tegra->sata_oob_rst)) { 525 + dev_err(&pdev->dev, "Failed to get sata-oob reset\n"); 526 + return PTR_ERR(tegra->sata_oob_rst); 527 + } 556 528 } 557 529 558 530 tegra->sata_cold_rst = devm_reset_control_get(&pdev->dev, "sata-cold");