Skip to content

Commit

Permalink
npu2-opencapi: Keep ODL and adapter in reset at the same time
Browse files Browse the repository at this point in the history
Split the function to assert and deassert the reset signal on the ODL,
so that we can keep the ODL in reset while we reset the adapter,
therefore having a window where both sides are in reset.

It is actually not required with our current DLx at boot time, but I
need to split the ODL reset function for the following patch and it
will become useful/required later when we introduce resetting an
opencapi link from the OS.

Signed-off-by: Frederic Barrat <fbarrat@linux.ibm.com>
Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
  • Loading branch information
fbarrat authored and stewartsmith committed Mar 14, 2019
1 parent 9f3cdff commit ce9dd46
Showing 1 changed file with 43 additions and 25 deletions.
68 changes: 43 additions & 25 deletions hw/npu2-opencapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@
#define OCAPI_SLOT_FRESET_INIT (OCAPI_SLOT_FRESET + 2)
#define OCAPI_SLOT_FRESET_ASSERT_DELAY (OCAPI_SLOT_FRESET + 3)
#define OCAPI_SLOT_FRESET_DEASSERT_DELAY (OCAPI_SLOT_FRESET + 4)
#define OCAPI_SLOT_FRESET_INIT_DELAY (OCAPI_SLOT_FRESET + 5)
#define OCAPI_SLOT_FRESET_DEASSERT_DELAY2 (OCAPI_SLOT_FRESET + 5)
#define OCAPI_SLOT_FRESET_INIT_DELAY (OCAPI_SLOT_FRESET + 6)

#define OCAPI_LINK_TRAINING_RETRIES 2
#define OCAPI_LINK_TRAINING_TIMEOUT 3000 /* ms */
Expand Down Expand Up @@ -261,6 +262,33 @@ static void set_transport_mux_controls(uint32_t gcid, uint32_t scom_base,
xscom_write(gcid, PU_IOE_PB_MISC_CFG, reg);
}

static void assert_odl_reset(uint32_t gcid, int index)
{
uint64_t reg, config_xscom;

config_xscom = OB_ODL_CONFIG(index);
/* Reset ODL */
reg = OB_ODL_CONFIG_RESET;
reg = SETFIELD(OB_ODL_CONFIG_VERSION, reg, 0b000001);
reg = SETFIELD(OB_ODL_CONFIG_TRAIN_MODE, reg, 0b0110);
reg = SETFIELD(OB_ODL_CONFIG_SUPPORTED_MODES, reg, 0b0010);
reg |= OB_ODL_CONFIG_X4_BACKOFF_ENABLE;
reg = SETFIELD(OB_ODL_CONFIG_PHY_CNTR_LIMIT, reg, 0b1111);
reg |= OB_ODL_CONFIG_DEBUG_ENABLE;
reg = SETFIELD(OB_ODL_CONFIG_FWD_PROGRESS_TIMER, reg, 0b0110);
xscom_write(gcid, config_xscom, reg);
}

static void deassert_odl_reset(uint32_t gcid, int index)
{
uint64_t reg, config_xscom;

config_xscom = OB_ODL_CONFIG(index);
xscom_read(gcid, config_xscom, &reg);
reg &= ~OB_ODL_CONFIG_RESET;
xscom_write(gcid, config_xscom, reg);
}

static void enable_odl_phy_mux(uint32_t gcid, int index)
{
uint64_t reg;
Expand Down Expand Up @@ -889,26 +917,6 @@ static void deassert_adapter_reset(struct npu2_dev *dev)
}
}

static void reset_odl(uint32_t gcid, struct npu2_dev *dev)
{
uint64_t reg, config_xscom;

config_xscom = OB_ODL_CONFIG(dev->brick_index);
/* Reset ODL */
reg = OB_ODL_CONFIG_RESET;
reg = SETFIELD(OB_ODL_CONFIG_VERSION, reg, 0b000001);
reg = SETFIELD(OB_ODL_CONFIG_TRAIN_MODE, reg, 0b0110);
reg = SETFIELD(OB_ODL_CONFIG_SUPPORTED_MODES, reg, 0b0010);
reg |= OB_ODL_CONFIG_X4_BACKOFF_ENABLE;
reg = SETFIELD(OB_ODL_CONFIG_PHY_CNTR_LIMIT, reg, 0b1111);
reg |= OB_ODL_CONFIG_DEBUG_ENABLE;
reg = SETFIELD(OB_ODL_CONFIG_FWD_PROGRESS_TIMER, reg, 0b0110);
xscom_write(gcid, config_xscom, reg);

reg &= ~OB_ODL_CONFIG_RESET;
xscom_write(gcid, config_xscom, reg);
}

static void setup_perf_counters(struct npu2_dev *dev)
{
uint64_t addr, reg, link;
Expand Down Expand Up @@ -1163,21 +1171,31 @@ static int64_t npu2_opencapi_freset(struct pci_slot *slot)
npu2_opencapi_phy_setup(dev);
/* fall-through */
case OCAPI_SLOT_FRESET_INIT:
reset_odl(chip_id, dev);
assert_odl_reset(chip_id, dev->brick_index);
assert_adapter_reset(dev);
pci_slot_set_state(slot,
OCAPI_SLOT_FRESET_ASSERT_DELAY);
/* assert for 5ms */
return pci_slot_set_sm_timeout(slot, msecs_to_tb(5));

case OCAPI_SLOT_FRESET_ASSERT_DELAY:
deassert_adapter_reset(dev);
deassert_odl_reset(chip_id, dev->brick_index);
pci_slot_set_state(slot,
OCAPI_SLOT_FRESET_DEASSERT_DELAY);
/* give another 5ms to device to be ready */
return pci_slot_set_sm_timeout(slot, msecs_to_tb(5));
/*
* Minimal delay before taking adapter out of
* reset. Could be useless, but doesn't hurt
*/
return pci_slot_set_sm_timeout(slot, msecs_to_tb(1));

case OCAPI_SLOT_FRESET_DEASSERT_DELAY:
deassert_adapter_reset(dev);
pci_slot_set_state(slot,
OCAPI_SLOT_FRESET_DEASSERT_DELAY2);
/* give 5ms to device to be ready */
return pci_slot_set_sm_timeout(slot, msecs_to_tb(5));

case OCAPI_SLOT_FRESET_DEASSERT_DELAY2:
if (dev->train_fenced) {
OCAPIDBG(dev, "Unfencing OTL after reset\n");
npu2_write(dev->npu, NPU2_MISC_FENCE_STATE,
Expand Down

0 comments on commit ce9dd46

Please sign in to comment.