1f73373
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
Jeremy Cline d1b6f8c
From: Robert Richter <rrichter@redhat.com>
Jeremy Cline d1b6f8c
Date: Thu, 7 Jun 2018 22:59:33 -0400
Jeremy Cline d1b6f8c
Subject: [PATCH] ahci: thunderx2: Fix for errata that affects stop engine
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
Message-id: <1528412373-19128-3-git-send-email-rrichter@redhat.com>
Jeremy Cline d1b6f8c
Patchwork-id: 220952
Jeremy Cline d1b6f8c
O-Subject: [RHEL-8.0 BZ 1563590 v2 2/2] ahci: thunderx2: Fix for errata that affects stop engine
Jeremy Cline d1b6f8c
Bugzilla: 1563590
Jeremy Cline d1b6f8c
RH-Acked-by: Dean Nelson <dnelson@redhat.com>
Jeremy Cline d1b6f8c
RH-Acked-by: Mark Langsdorf <mlangsdo@redhat.com>
Jeremy Cline d1b6f8c
RH-Acked-by: Mark Salter <msalter@redhat.com>
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
From: Jayachandran C <jnair@caviumnetworks.com>
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
Apply workaround for this errata:
Jeremy Cline d1b6f8c
  Synopsis: Resetting PxCMD.ST may hang the SATA device
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
  Description: An internal ping-pong buffer state is not reset
Jeremy Cline d1b6f8c
  correctly for an PxCMD.ST=0 command for a SATA channel. This
Jeremy Cline d1b6f8c
  may cause the SATA interface to hang when a PxCMD.ST=0 command
Jeremy Cline d1b6f8c
  is received.
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
  Workaround: A SATA_BIU_CORE_ENABLE.sw_init_bsi must be asserted
Jeremy Cline d1b6f8c
  by the driver whenever the PxCMD.ST needs to be de-asserted. This
Jeremy Cline d1b6f8c
  will reset both the ports. So, it may not always work in a 2
Jeremy Cline d1b6f8c
  channel SATA system.
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
  Resolution: Fix in B0.
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
Add the code to ahci_stop_engine() to do this. It is not easy to
Jeremy Cline d1b6f8c
stop the other "port" since it is associated with a different AHCI
Jeremy Cline d1b6f8c
interface. Please note that with this fix, SATA reset does not
Jeremy Cline d1b6f8c
hang any more, but it can cause failures on the other interface
Jeremy Cline d1b6f8c
if that is in active use.
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
Unfortunately, we have nothing other the the CPU ID to check if the
Jeremy Cline d1b6f8c
SATA block has this issue.
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
RHEL-only:
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
Both patches are in RHEL-7.6 also. Inclusion of the patches into RHEL-8
Jeremy Cline d1b6f8c
was discussed. Since there are partners with Ax system configurations it
Jeremy Cline d1b6f8c
was decided to carry them in RHEL8 too. See:
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
 https://bugzilla.redhat.com/show_bug.cgi?id=1563590#c1
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
[v3 with new delays]
Jeremy Cline d1b6f8c
Signed-off-by: Jayachandran C <jnair@caviumnetworks.com>
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
Upstream Status: RHEL only
Jeremy Cline d1b6f8c
Signed-off-by: Robert Richter <rrichter@redhat.com>
Jeremy Cline d1b6f8c
Signed-off-by: Herton R. Krzesinski <herton@redhat.com>
Jeremy Cline d1b6f8c
---
Jeremy Cline d1b6f8c
 drivers/ata/libahci.c | 18 ++++++++++++++++++
Jeremy Cline d1b6f8c
 1 file changed, 18 insertions(+)
Jeremy Cline d1b6f8c
Jeremy Cline d1b6f8c
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
Jeremy Cline d1b6f8c
index ea5bf5f4cbed..71c55cae27ac 100644
Jeremy Cline d1b6f8c
--- a/drivers/ata/libahci.c
Jeremy Cline d1b6f8c
+++ b/drivers/ata/libahci.c
Jeremy Cline d1b6f8c
@@ -666,6 +666,24 @@ int ahci_stop_engine(struct ata_port *ap)
Jeremy Cline d1b6f8c
 	tmp &= ~PORT_CMD_START;
Jeremy Cline d1b6f8c
 	writel(tmp, port_mmio + PORT_CMD);
d176dfc
Jeremy Cline d1b6f8c
+#ifdef CONFIG_ARM64
Jeremy Cline d1b6f8c
+	/* Rev Ax of Cavium CN99XX needs a hack for port stop */
Jeremy Cline d1b6f8c
+	if (dev_is_pci(ap->host->dev) &&
Jeremy Cline d1b6f8c
+	    to_pci_dev(ap->host->dev)->vendor == 0x14e4 &&
Jeremy Cline d1b6f8c
+	    to_pci_dev(ap->host->dev)->device == 0x9027 &&
Jeremy Cline d1b6f8c
+	    midr_is_cpu_model_range(read_cpuid_id(),
Jeremy Cline d1b6f8c
+			MIDR_CPU_MODEL(ARM_CPU_IMP_BRCM, BRCM_CPU_PART_VULCAN),
Jeremy Cline d1b6f8c
+			MIDR_CPU_VAR_REV(0, 0),
Jeremy Cline d1b6f8c
+			MIDR_CPU_VAR_REV(0, MIDR_REVISION_MASK))) {
Jeremy Cline d1b6f8c
+		tmp = readl(hpriv->mmio + 0x8000);
Jeremy Cline d1b6f8c
+		udelay(100);
Jeremy Cline d1b6f8c
+		writel(tmp | (1 << 26), hpriv->mmio + 0x8000);
Jeremy Cline d1b6f8c
+		udelay(100);
Jeremy Cline d1b6f8c
+		writel(tmp & ~(1 << 26), hpriv->mmio + 0x8000);
Jeremy Cline d1b6f8c
+		dev_warn(ap->host->dev, "CN99XX SATA reset workaround applied\n");
Jeremy Cline d1b6f8c
+	}
Jeremy Cline d1b6f8c
+#endif
Jeremy Cline d1b6f8c
+
Jeremy Cline d1b6f8c
 	/* wait for engine to stop. This could be as long as 500 msec */
Jeremy Cline d1b6f8c
 	tmp = ata_wait_register(ap, port_mmio + PORT_CMD,
Jeremy Cline d1b6f8c
 				PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500);
Jeremy Cline d1b6f8c
-- 
73c86eb
2.28.0
Jeremy Cline d1b6f8c