summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/tegra/ahci_tegra.c194
-rw-r--r--drivers/ata/tegra/ahci_tegra.h12
-rw-r--r--drivers/ata/tegra/ahci_tegra_debug.c14
3 files changed, 207 insertions, 13 deletions
diff --git a/drivers/ata/tegra/ahci_tegra.c b/drivers/ata/tegra/ahci_tegra.c
index daff70ff7..c22baf78a 100644
--- a/drivers/ata/tegra/ahci_tegra.c
+++ b/drivers/ata/tegra/ahci_tegra.c
@@ -24,6 +24,7 @@ static void tegra_ahci_power_off(struct ahci_host_priv *hpriv);
24static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv); 24static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv);
25static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv); 25static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv);
26static int tegra_ahci_quirks(struct ahci_host_priv *hpriv); 26static int tegra_ahci_quirks(struct ahci_host_priv *hpriv);
27static int tegra_ahci_disable_features(struct ahci_host_priv *hpriv);
27static struct ahci_host_priv * 28static struct ahci_host_priv *
28tegra_ahci_platform_get_resources(struct tegra_ahci_priv *); 29tegra_ahci_platform_get_resources(struct tegra_ahci_priv *);
29#ifdef CONFIG_PM_RUNTIME 30#ifdef CONFIG_PM_RUNTIME
@@ -73,6 +74,7 @@ static int tegra_ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
73 struct ata_device *dev; 74 struct ata_device *dev;
74 int ret = 0; 75 int ret = 0;
75 u32 port_status = 0; 76 u32 port_status = 0;
77 enum tegra_ahci_port_runtime_status lpm_state;
76 int i; 78 int i;
77 79
78 ata_for_each_link(link, ap, PMP_FIRST) { 80 ata_for_each_link(link, ap, PMP_FIRST) {
@@ -85,24 +87,36 @@ static int tegra_ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
85 bool dipm = ata_id_has_dipm(dev->id) && 87 bool dipm = ata_id_has_dipm(dev->id) &&
86 (!(link->ap->flags & ATA_FLAG_NO_DIPM)); 88 (!(link->ap->flags & ATA_FLAG_NO_DIPM));
87 89
90 if (ap->target_lpm_policy == ATA_LPM_MIN_POWER) {
91 if ((hpriv->cap2 & HOST_CAP2_SDS) &&
92 (hpriv->cap2 & HOST_CAP2_SADM) &&
93 (link->device->flags & ATA_DFLAG_DEVSLP))
94 lpm_state =
95 TEGRA_AHCI_PORT_RUNTIME_DEVSLP;
96 else
97 lpm_state =
98 TEGRA_AHCI_PORT_RUNTIME_SLUMBER;
99 } else if (ap->target_lpm_policy == ATA_LPM_MED_POWER) {
100 lpm_state = TEGRA_AHCI_PORT_RUNTIME_PARTIAL;
101 } else {
102 lpm_state = TEGRA_AHCI_PORT_RUNTIME_ACTIVE;
103 }
104
88 if (hipm || dipm) { 105 if (hipm || dipm) {
89 for (i = 0; i < TEGRA_AHCI_SLUMBER_TIMEOUT; 106 for (i = 0; i < TEGRA_AHCI_LPM_TIMEOUT; i++) {
90 i++) {
91 port_status = tegra_ahci_bar5_readl( 107 port_status = tegra_ahci_bar5_readl(
92 hpriv, T_AHCI_PORT_PXSSTS); 108 hpriv, T_AHCI_PORT_PXSSTS);
93 port_status = 109 port_status =
94 (port_status & 110 (port_status &
95 T_AHCI_PORT_PXSSTS_IPM_MASK) 111 T_AHCI_PORT_PXSSTS_IPM_MASK)
96 >> T_AHCI_PORT_PXSSTS_IPM_SHIFT; 112 >> T_AHCI_PORT_PXSSTS_IPM_SHIFT;
97 if (port_status < 113 if (port_status < lpm_state)
98 TEGRA_AHCI_PORT_RUNTIME_SLUMBER)
99 mdelay(10); 114 mdelay(10);
100 else 115 else
101 break; 116 break;
102 } 117 }
103 118
104 if (port_status < 119 if (port_status < lpm_state) {
105 TEGRA_AHCI_PORT_RUNTIME_SLUMBER) {
106 ata_link_err(link, 120 ata_link_err(link,
107 "Link didn't enter LPM\n"); 121 "Link didn't enter LPM\n");
108 return -EBUSY; 122 return -EBUSY;
@@ -177,7 +191,7 @@ static struct ata_port_operations ahci_tegra_port_ops = {
177 .port_resume = tegra_ahci_port_resume, 191 .port_resume = tegra_ahci_port_resume,
178}; 192};
179 193
180static const struct ata_port_info ahci_tegra_port_info = { 194static struct ata_port_info ahci_tegra_port_info = {
181 .flags = AHCI_FLAG_COMMON, 195 .flags = AHCI_FLAG_COMMON,
182 .pio_mask = ATA_PIO4, 196 .pio_mask = ATA_PIO4,
183 .udma_mask = ATA_UDMA6, 197 .udma_mask = ATA_UDMA6,
@@ -370,6 +384,8 @@ static int tegra_ahci_elpg_exit(struct ata_host *host)
370 struct ahci_host_priv *hpriv = host->private_data; 384 struct ahci_host_priv *hpriv = host->private_data;
371 struct tegra_ahci_priv *tegra = hpriv->plat_data; 385 struct tegra_ahci_priv *tegra = hpriv->plat_data;
372 int ret = 0; 386 int ret = 0;
387 u32 val;
388 u32 mask;
373 int i; 389 int i;
374 390
375 /* 1. unpowergate */ 391 /* 1. unpowergate */
@@ -391,9 +407,13 @@ static int tegra_ahci_elpg_exit(struct ata_host *host)
391 T_SATA0_CFG_POWER_GATE); 407 T_SATA0_CFG_POWER_GATE);
392 408
393 /* 3. If devslp asserted, de-assert devslp */ 409 /* 3. If devslp asserted, de-assert devslp */
394 if (tegra->devslp_override) 410 if (tegra->devslp_override) {
395 tegra_ahci_override_devslp(hpriv, false); 411 tegra_ahci_override_devslp(hpriv, false);
396 412
413 val = mask = MDAT_TIMER_AFTER_PG_VALID;
414 tegra_ahci_aux_update(hpriv, val, mask, SATA_AUX_SPARE_CFG0_0);
415 }
416
397 /* 4. Program a register in the PMC to indicate to SATA that it is 417 /* 4. Program a register in the PMC to indicate to SATA that it is
398 * entering power gating. This shall drive the pmc2sata_pg_info 418 * entering power gating. This shall drive the pmc2sata_pg_info
399 * signal 419 * signal
@@ -401,6 +421,12 @@ static int tegra_ahci_elpg_exit(struct ata_host *host)
401 tegra_pmc_sata_pwrgt_update(PMC_IMPL_SATA_PWRGT_0_PG_INFO, 421 tegra_pmc_sata_pwrgt_update(PMC_IMPL_SATA_PWRGT_0_PG_INFO,
402 ~PMC_IMPL_SATA_PWRGT_0_PG_INFO); 422 ~PMC_IMPL_SATA_PWRGT_0_PG_INFO);
403 423
424 if (tegra->devslp_override) {
425 tegra->devslp_override = false;
426 val = mask = T_SATA0_CFG_POWER_GATE_POWER_UNGATE_COMP;
427 tegra_ahci_scfg_update(hpriv, val, mask,
428 T_SATA0_CFG_POWER_GATE);
429 }
404 /* 430 /*
405 * 5. Program the UPHY_LANE registers to bring up UPHY from IDDQ 431 * 5. Program the UPHY_LANE registers to bring up UPHY from IDDQ
406 */ 432 */
@@ -693,6 +719,12 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
693 T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN); 719 T_SATA0_CFG_PHY_1_PAD_PLL_IDDQ_EN);
694 tegra_ahci_scfg_update(hpriv, val, val, T_SATA0_CFG_PHY_1); 720 tegra_ahci_scfg_update(hpriv, val, val, T_SATA0_CFG_PHY_1);
695 721
722 /*
723 * Indicate Sata only has the capability to enter DevSleep
724 * from slumber link.
725 */
726 tegra_ahci_aux_update(hpriv, DESO_SUPPORT, DESO_SUPPORT,
727 SATA_AUX_MISC_CNTL_1_0);
696 /* Enabling IPFS Clock Gating */ 728 /* Enabling IPFS Clock Gating */
697 mask = SATA_CONFIGURATION_CLK_OVERRIDE; 729 mask = SATA_CONFIGURATION_CLK_OVERRIDE;
698 val = (u32) ~SATA_CONFIGURATION_CLK_OVERRIDE; 730 val = (u32) ~SATA_CONFIGURATION_CLK_OVERRIDE;
@@ -701,7 +733,9 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
701 val = IP_INT_MASK; 733 val = IP_INT_MASK;
702 tegra_ahci_sata_update(hpriv, val, val, SATA_INTR_MASK_0); 734 tegra_ahci_sata_update(hpriv, val, val, SATA_INTR_MASK_0);
703 735
704 return 0; 736 ret = tegra_ahci_disable_features(hpriv);
737
738 return ret;
705} 739}
706 740
707static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv) 741static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
@@ -716,6 +750,75 @@ static void tegra_ahci_controller_deinit(struct ahci_host_priv *hpriv)
716 pm_runtime_disable(dev); 750 pm_runtime_disable(dev);
717} 751}
718 752
753static void tegra_ahci_disable_devslp(struct ahci_host_priv *hpriv)
754{
755 u32 val = 0;
756 u32 mask = SDS_SUPPORT;
757
758 val = 0xFFFFFFFF & ~SDS_SUPPORT;
759 tegra_ahci_aux_update(hpriv, val, mask, SATA_AUX_MISC_CNTL_1_0);
760}
761
762static void tegra_ahci_disable_hipm(struct ahci_host_priv *hpriv)
763{
764 u32 val = 0;
765 u32 mask = T_SATA0_AHCI_HBA_CAP_BKDR_SALP;
766
767 val = 0xFFFFFFFF & ~T_SATA0_AHCI_HBA_CAP_BKDR_SALP;
768 tegra_ahci_scfg_update(hpriv, val, mask, T_SATA0_AHCI_HBA_CAP_BKDR);
769}
770
771static void tegra_ahci_disable_ncq(struct ahci_host_priv *hpriv)
772{
773 u32 val = 0;
774 u32 mask = T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ;
775
776 val = 0xFFFFFFFF & ~T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ;
777 tegra_ahci_scfg_update(hpriv, val, mask, T_SATA0_AHCI_HBA_CAP_BKDR);
778}
779
780static int tegra_ahci_disable_features(struct ahci_host_priv *hpriv)
781{
782 struct tegra_ahci_priv *tegra = hpriv->plat_data;
783 struct platform_device *pdev = tegra->pdev;
784 struct device *dev = &pdev->dev;
785 struct device_node *np = dev->of_node;
786 struct property *prop;
787 const char *feature;
788 bool devslp_enabled = true;
789 int ret = 0;
790
791 if (of_property_count_strings(np, "nvidia,disable-features") <= 0)
792 return 0;
793
794 of_property_for_each_string(np, "nvidia,disable-features", prop,
795 feature) {
796 if (!strcmp(feature, "devslp")) {
797 tegra_ahci_disable_devslp(hpriv);
798 devslp_enabled = false;
799 } else if (!strcmp(feature, "hipm")) {
800 tegra_ahci_disable_hipm(hpriv);
801 } else if (!strcmp(feature, "ncq")) {
802 tegra_ahci_disable_ncq(hpriv);
803 } else if (!strcmp(feature, "dipm")) {
804 ahci_tegra_port_info.flags |= ATA_FLAG_NO_DIPM;
805 }
806 }
807
808 if (devslp_enabled) {
809 if (tegra->devslp_pin) {
810 ret = pinctrl_select_state(tegra->devslp_pin,
811 tegra->devslp_active);
812 if (ret < 0) {
813 dev_err(&pdev->dev,
814 "setting devslp pin state failed\n");
815 return ret;
816 }
817 }
818 }
819 return ret;
820}
821
719static int tegra_ahci_quirks(struct ahci_host_priv *hpriv) 822static int tegra_ahci_quirks(struct ahci_host_priv *hpriv)
720{ 823{
721 unsigned int val; 824 unsigned int val;
@@ -842,6 +945,45 @@ err_out:
842 return ret; 945 return ret;
843} 946}
844 947
948static int tegra_ahci_set_lpm(struct ahci_host_priv *hpriv)
949{
950 struct tegra_ahci_priv *tegra = hpriv->plat_data;
951 struct platform_device *pdev = tegra->pdev;
952 struct device *dev = &pdev->dev;
953 struct ata_host *host = dev_get_drvdata(dev);
954 struct device_node *np = dev->of_node;
955 struct property *prop;
956 const char *feature;
957 enum ata_lpm_policy policy = ATA_LPM_MAX_POWER;
958 int ret = 0;
959 int i;
960
961 if (of_property_count_strings(np, "nvidia,link-flags") <= 0)
962 return 0;
963
964 of_property_for_each_string(np, "nvidia,link-flags", prop,
965 feature) {
966 if (!strcmp(feature, "min_power"))
967 policy = ATA_LPM_MIN_POWER;
968 else if (!strcmp(feature, "max_power"))
969 policy = ATA_LPM_MAX_POWER;
970 else if (!strcmp(feature, "med_power"))
971 policy = ATA_LPM_MED_POWER;
972 }
973
974 if (policy > ATA_LPM_MAX_POWER) {
975 for (i = 0; i < host->n_ports; i++) {
976 struct ata_port *ap = host->ports[i];
977
978 ap->target_lpm_policy = policy;
979 ata_port_schedule_eh(ap);
980 }
981
982 }
983 return ret;
984}
985
986
845static struct ahci_host_priv * 987static struct ahci_host_priv *
846tegra_ahci_platform_get_resources(struct tegra_ahci_priv *tegra) 988tegra_ahci_platform_get_resources(struct tegra_ahci_priv *tegra)
847{ 989{
@@ -853,11 +995,36 @@ tegra_ahci_platform_get_resources(struct tegra_ahci_priv *tegra)
853 int i; 995 int i;
854 996
855 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL); 997 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
856 if (!hpriv) 998 if (!hpriv) {
999 ret = PTR_ERR(hpriv);
857 goto err_out; 1000 goto err_out;
1001 }
858 1002
859 hpriv->plat_data = tegra; 1003 hpriv->plat_data = tegra;
860 1004
1005 tegra->devslp_pin = devm_pinctrl_get(dev);
1006 if (IS_ERR(tegra->devslp_pin)) {
1007 dev_warn(dev, "Missing devslp pinctrl\n");
1008 tegra->devslp_pin = NULL;
1009 }
1010
1011 if (tegra->devslp_pin) {
1012 tegra->devslp_active = pinctrl_lookup_state(tegra->devslp_pin,
1013 "devslp_active");
1014 if (IS_ERR(tegra->devslp_active)) {
1015 dev_err(dev, "Missing devslp-active state\n");
1016 ret = PTR_ERR(tegra->devslp_active);
1017 goto err_out;
1018 }
1019 tegra->devslp_pullup = pinctrl_lookup_state(tegra->devslp_pin,
1020 "devslp_pullup");
1021 if (IS_ERR(tegra->devslp_pullup)) {
1022 dev_err(dev, "Missing devslp-pullup state\n");
1023 ret = PTR_ERR(tegra->devslp_pullup);
1024 goto err_out;
1025 }
1026 }
1027
861 ret = tegra_ahci_platform_get_memory_resources(tegra); 1028 ret = tegra_ahci_platform_get_memory_resources(tegra);
862 if (ret) 1029 if (ret)
863 goto err_out; 1030 goto err_out;
@@ -969,6 +1136,13 @@ static int tegra_ahci_probe(struct platform_device *pdev)
969 if (ret) 1136 if (ret)
970 goto poweroff_controller; 1137 goto poweroff_controller;
971 1138
1139 ret = tegra_ahci_set_lpm(hpriv);
1140 if (ret) {
1141 dev_err(&pdev->dev,
1142 "Failed to set lpm\n");
1143 goto poweroff_controller;
1144 }
1145
972 ret = pm_runtime_set_active(&pdev->dev); 1146 ret = pm_runtime_set_active(&pdev->dev);
973 if (ret) { 1147 if (ret) {
974 dev_dbg(&pdev->dev, "unable to set runtime pm active err=%d\n", 1148 dev_dbg(&pdev->dev, "unable to set runtime pm active err=%d\n",
diff --git a/drivers/ata/tegra/ahci_tegra.h b/drivers/ata/tegra/ahci_tegra.h
index aa4c9cd88..3aba972b3 100644
--- a/drivers/ata/tegra/ahci_tegra.h
+++ b/drivers/ata/tegra/ahci_tegra.h
@@ -40,6 +40,11 @@
40 40
41#define SATA_AUX_MISC_CNTL_1_0 0x8 41#define SATA_AUX_MISC_CNTL_1_0 0x8
42#define DEVSLP_OVERRIDE BIT(17) 42#define DEVSLP_OVERRIDE BIT(17)
43#define SDS_SUPPORT BIT(13)
44#define DESO_SUPPORT BIT(15)
45
46#define SATA_AUX_SPARE_CFG0_0 0x18
47#define MDAT_TIMER_AFTER_PG_VALID BIT(14)
43 48
44/* IPFS Register Space */ 49/* IPFS Register Space */
45#define SATA_CONFIGURATION_0 0x180 50#define SATA_CONFIGURATION_0 0x180
@@ -81,6 +86,7 @@
81#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP BIT(14) 86#define T_SATA0_AHCI_HBA_CAP_BKDR_SLUMBER_ST_CAP BIT(14)
82#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP BIT(26) 87#define T_SATA0_AHCI_HBA_CAP_BKDR_SALP BIT(26)
83#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM BIT(17) 88#define T_SATA0_AHCI_HBA_CAP_BKDR_SUPP_PM BIT(17)
89#define T_SATA0_AHCI_HBA_CAP_BKDR_SNCQ BIT(30)
84 90
85#define T_SATA_CFG_PHY_0 0x120 91#define T_SATA_CFG_PHY_0 0x120
86#define T_SATA_CFG_PHY_0_MASK_SQUELCH BIT(24) 92#define T_SATA_CFG_PHY_0_MASK_SQUELCH BIT(24)
@@ -120,6 +126,7 @@
120 126
121#define T_SATA0_CFG_POWER_GATE 0x4AC 127#define T_SATA0_CFG_POWER_GATE 0x4AC
122#define T_SATA0_CFG_POWER_GATE_SSTS_RESTORED BIT(23) 128#define T_SATA0_CFG_POWER_GATE_SSTS_RESTORED BIT(23)
129#define T_SATA0_CFG_POWER_GATE_POWER_UNGATE_COMP BIT(1)
123 130
124 131
125/* AHCI registers */ 132/* AHCI registers */
@@ -137,7 +144,7 @@
137 144
138#define TEGRA_AHCI_MAX_CLKS 2 145#define TEGRA_AHCI_MAX_CLKS 2
139#define TEGRA_AHCI_DEFAULT_IDLE_TIME 10000 146#define TEGRA_AHCI_DEFAULT_IDLE_TIME 10000
140#define TEGRA_AHCI_SLUMBER_TIMEOUT 50 147#define TEGRA_AHCI_LPM_TIMEOUT 500
141 148
142enum tegra_sata_bars { 149enum tegra_sata_bars {
143 TEGRA_SATA_IPFS = 0, 150 TEGRA_SATA_IPFS = 0,
@@ -167,6 +174,9 @@ struct tegra_ahci_priv {
167 struct clk *sata_oob_clk; 174 struct clk *sata_oob_clk;
168 struct clk *pllp_clk; /* sata_oob clk parent */ 175 struct clk *pllp_clk; /* sata_oob clk parent */
169 struct clk *pllp_uphy_clk; /* sata_clk parent */ 176 struct clk *pllp_uphy_clk; /* sata_clk parent */
177 struct pinctrl *devslp_pin;
178 struct pinctrl_state *devslp_active;
179 struct pinctrl_state *devslp_pullup;
170 bool devslp_override; 180 bool devslp_override;
171 bool devslp_pinmux_override; 181 bool devslp_pinmux_override;
172}; 182};
diff --git a/drivers/ata/tegra/ahci_tegra_debug.c b/drivers/ata/tegra/ahci_tegra_debug.c
index df8c5c1c1..0e6d0ce4c 100644
--- a/drivers/ata/tegra/ahci_tegra_debug.c
+++ b/drivers/ata/tegra/ahci_tegra_debug.c
@@ -46,19 +46,26 @@ tegra_ahci_dbg_print_regs(struct seq_file *s, u32 *ptr, u32 base, u32 regs)
46 46
47int tegra_ahci_dbg_dump_show(struct seq_file *s, void *data) 47int tegra_ahci_dbg_dump_show(struct seq_file *s, void *data)
48{ 48{
49 struct ahci_host_priv *hpriv = s->private; 49 struct ahci_host_priv *hpriv = NULL;
50 struct tegra_ahci_priv *tegra = NULL; 50 struct tegra_ahci_priv *tegra = NULL;
51 u32 base; 51 u32 base;
52 u32 *ptr; 52 u32 *ptr;
53 u32 i; 53 u32 i;
54 54
55 if (s)
56 hpriv = s->private;
57 else
58 hpriv = data;
59
55 tegra = hpriv->plat_data; 60 tegra = hpriv->plat_data;
56 61
62 tegra_ahci_scfg_writel(hpriv, T_SATA0_INDEX_CH1, T_SATA0_INDEX);
63
57 base = tegra->res[TEGRA_SATA_CONFIG]->start; 64 base = tegra->res[TEGRA_SATA_CONFIG]->start;
58 ptr = tegra->base_list[TEGRA_SATA_CONFIG]; 65 ptr = tegra->base_list[TEGRA_SATA_CONFIG];
59 TEGRA_AHCI_DUMP_STRING(s, "SATA CONFIG Registers:\n"); 66 TEGRA_AHCI_DUMP_STRING(s, "SATA CONFIG Registers:\n");
60 TEGRA_AHCI_DUMP_STRING(s, "----------------------\n"); 67 TEGRA_AHCI_DUMP_STRING(s, "----------------------\n");
61 tegra_ahci_dbg_print_regs(s, ptr, base, 0x200); 68 tegra_ahci_dbg_print_regs(s, ptr, base, 0x400);
62 69
63 base = tegra->res[TEGRA_SATA_AHCI]->start; 70 base = tegra->res[TEGRA_SATA_AHCI]->start;
64 ptr = hpriv->mmio; 71 ptr = hpriv->mmio;
@@ -74,6 +81,9 @@ int tegra_ahci_dbg_dump_show(struct seq_file *s, void *data)
74 tegra_ahci_dbg_print_regs(s, ptr, base, 20); 81 tegra_ahci_dbg_print_regs(s, ptr, base, 20);
75 } 82 }
76 83
84 tegra_ahci_scfg_writel(hpriv, T_SATA0_INDEX_NONE_SELECTED,
85 T_SATA0_INDEX);
86
77 return 0; 87 return 0;
78} 88}
79 89