[Skiboot] [PATCH 2/3] npu2-hw-procedures: Fix zcal in mixed opencapi and nvlink mode

Frederic Barrat fbarrat at linux.ibm.com
Sat Mar 16 03:44:39 AEDT 2019


The zcal procedure needs to be run once per obus. We keep track of
which obus is already calibrated in an array indexed by the obus
number. However, the obus number is inferred from the brick index,
which works well for nvlink but not for opencapi.

Create an obus_index() function, which, from a device, returns the
correct obus index, irrespective of the device type.

Signed-off-by: Frederic Barrat <fbarrat at linux.ibm.com>
---
 hw/npu2-hw-procedures.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/hw/npu2-hw-procedures.c b/hw/npu2-hw-procedures.c
index 3ee646cd..2f330957 100644
--- a/hw/npu2-hw-procedures.c
+++ b/hw/npu2-hw-procedures.c
@@ -201,11 +201,29 @@ static uint32_t nop(struct npu2_dev *npu_dev __unused)
 }
 DEFINE_PROCEDURE(nop);
 
-/* Return the brick number (0-2) within an obus chiplet */
+/*
+ * Return the obus (0 or 1) of a device
+ *
+ * Using the brick index is dangerous, because it varies for a link
+ * depending on the mode (opencapi or nvlink)
+ */
+static int obus_index(struct npu2_dev *ndev)
+{
+	if ((ndev->pl_xscom_base & 0x3F000000) == 0x09000000)
+		return 0;
+	else
+		return 1;
+}
+
+/*
+ * Return the brick number (0-2) within an obus chiplet.
+ * Only valid for nvlink devices
+ */
 static int obus_brick_index(struct npu2_dev *ndev)
 {
 	int index = ndev->brick_index % 3;
 
+	assert(ndev->type != NPU2_DEV_TYPE_OPENCAPI);
 	/* On the second obus chiplet, index is reversed */
 	if ((ndev->pl_xscom_base & 0x3F000000) != 0x09000000)
 		return 2 - index;
@@ -441,7 +459,7 @@ DEFINE_PROCEDURE(phy_reset, phy_reset_wait, phy_reset_complete);
 /* Procedure 1.2.6 - I/O PHY Tx Impedance Calibration */
 static uint32_t phy_tx_zcal(struct npu2_dev *ndev)
 {
-	if (ndev->npu->tx_zcal_complete[ndev->brick_index > 2])
+	if (ndev->npu->tx_zcal_complete[obus_index(ndev)])
 		return PROCEDURE_COMPLETE;
 
 	/* Turn off SW enable and enable zcal state machine */
@@ -612,7 +630,7 @@ static uint32_t phy_tx_zcal_calculate(struct npu2_dev *ndev)
 	phy_write(ndev, &NPU2_PHY_TX_MARGINPU_SELECT, therm(margin_select + 1)/2);
 	phy_write(ndev, &NPU2_PHY_TX_MARGINPD_SELECT, therm(margin_select + 1)/2);
 
-	ndev->npu->tx_zcal_complete[ndev->brick_index > 2] = 1;
+	ndev->npu->tx_zcal_complete[obus_index(ndev)] = 1;
 	return PROCEDURE_COMPLETE;
 }
 DEFINE_PROCEDURE(phy_tx_zcal, phy_tx_zcal_wait, phy_tx_zcal_calculate);
-- 
2.19.1



More information about the Skiboot mailing list