summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinivas Pandruvada <srinivas.pandruvada@linux.intel.com>2018-07-02 15:01:54 -0400
committerTejun Heo <tj@kernel.org>2018-07-30 13:33:18 -0400
commit11c291461b6ea8d1195a96d6bba6673a94aacebc (patch)
tree1688bf2e1a1cf0617b92e5d4966e0cdd28e7a03f
parent2dbb3ec29a6c069035857a2fc4c24e80e5dfe3cc (diff)
ata: libahci: Allow reconfigure of DEVSLP register
There are two modes in which DEVSLP can be entered. The OS initiated or hardware autonomous. In hardware autonomous mode, BIOS configures the AHCI controller and the device to enable DEVSLP. But they may not be ideal for all cases. So in this case, OS should be able to reconfigure DEVSLP register. Currently if the DEVSLP is already enabled, we can't set again as it will simply return. There are some systems where the firmware is setting high DITO by default, in this case we can't modify here to correct settings. With the default in several seconds, we are not able to transition to DEVSLP. This change will allow reconfiguration of devslp register if DITO is different. Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--drivers/ata/libahci.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index fdb7d7bf7626..313fd74ddaef 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -2107,7 +2107,7 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
2107 struct ahci_host_priv *hpriv = ap->host->private_data; 2107 struct ahci_host_priv *hpriv = ap->host->private_data;
2108 void __iomem *port_mmio = ahci_port_base(ap); 2108 void __iomem *port_mmio = ahci_port_base(ap);
2109 struct ata_device *dev = ap->link.device; 2109 struct ata_device *dev = ap->link.device;
2110 u32 devslp, dm, dito, mdat, deto; 2110 u32 devslp, dm, dito, mdat, deto, dito_conf;
2111 int rc; 2111 int rc;
2112 unsigned int err_mask; 2112 unsigned int err_mask;
2113 2113
@@ -2131,8 +2131,15 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
2131 return; 2131 return;
2132 } 2132 }
2133 2133
2134 /* device sleep was already enabled */ 2134 dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
2135 if (devslp & PORT_DEVSLP_ADSE) 2135 dito = devslp_idle_timeout / (dm + 1);
2136 if (dito > 0x3ff)
2137 dito = 0x3ff;
2138
2139 dito_conf = (devslp >> PORT_DEVSLP_DITO_OFFSET) & 0x3FF;
2140
2141 /* device sleep was already enabled and same dito */
2142 if ((devslp & PORT_DEVSLP_ADSE) && (dito_conf == dito))
2136 return; 2143 return;
2137 2144
2138 /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */ 2145 /* set DITO, MDAT, DETO and enable DevSlp, need to stop engine first */
@@ -2140,11 +2147,6 @@ static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
2140 if (rc) 2147 if (rc)
2141 return; 2148 return;
2142 2149
2143 dm = (devslp & PORT_DEVSLP_DM_MASK) >> PORT_DEVSLP_DM_OFFSET;
2144 dito = devslp_idle_timeout / (dm + 1);
2145 if (dito > 0x3ff)
2146 dito = 0x3ff;
2147
2148 /* Use the nominal value 10 ms if the read MDAT is zero, 2150 /* Use the nominal value 10 ms if the read MDAT is zero,
2149 * the nominal value of DETO is 20 ms. 2151 * the nominal value of DETO is 20 ms.
2150 */ 2152 */