[Skiboot] [PATCH 2/4] hw/npu2: Combined NPU brick configuration procedure

Frederic Barrat fbarrat at linux.ibm.com
Fri Oct 19 17:09:05 AEDT 2018



Le 19/10/2018 à 08:07, Frederic Barrat a écrit :
> 
> 
> Le 19/10/2018 à 03:30, Andrew Donnellan a écrit :
>> On 19/10/18 3:04 am, Frederic Barrat wrote:
>>>> +        /* Disable NV-Link link layers */
>>>> +        xscom_read(npu->chip_id, phy_config_scom, &reg);
>>>> +        reg &= ~OBUS_IOOL_PHY_CONFIG_NV0_NPU_ENABLED;
>>>> +        reg &= ~OBUS_IOOL_PHY_CONFIG_NV1_NPU_ENABLED;
>>>> +        reg &= ~OBUS_IOOL_PHY_CONFIG_NV2_NPU_ENABLED;
>>>> +        xscom_write(npu->chip_id, phy_config_scom, reg);
>>>> +    }
>>>
>>> If there's one opencapi device, we disable nvlink for the 3 links of 
>>> the obus. So even if the opencapi device is on slot GPU#1, doesn't it 
>>> mean a GPU on slot GPU#0 would also be in degraded mode (2 links 
>>> instead of 3)?
>>> Which would have an impact on the previous patch.
>>
>> I'm not sure what you're getting at here - if a GPU is in slot GPU#0, 
>> then all 3 of its links will be on OBUS0.
> 
> I was worried about opencapi settings creeping on a 2nd stack, thus 
> polluting it and making the 2nd stack useless for nvlink. But come to 
> think of it, it's probably fine. We're breaking one link of the 2nd, 
> nvlink stack, but since the link is not used, no harm is done. The other 
> link of the 2nd stack, on obus3, would be defined correctly.

Arg, I need coffee: obus3 --> obus0

> 
>    Fred
> 
> 
>>
>>
>> Andrew
>>
>>>
>>> I guess the question is whether we could keep 1 link in nvidia-mode.
>>>
>>>    Fred
>>>
>>>
>>>> +
>>>> +    /* Optical IO Transport Mux Config for Bricks 0-2 and 4-5 */
>>>> +    reg = npu2_scom_read(npu->chip_id, npu->xscom_base, 
>>>> NPU2_MISC_OPTICAL_IO_CFG0,
>>>> +                 NPU2_MISC_DA_LEN_8B);
>>>> +    ndlmux_brk0to2 = 
>>>> GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_NDLMUX_BRK0TO2, reg);
>>>> +    ocmux_brk0to1 = 
>>>> GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK0TO1, reg);
>>>> +    ocmux_brk4to5 = 
>>>> GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK4TO5, reg);
>>>> +    for (int i = 0; i < npu->total_devices; i++) {
>>>> +            dev = &npu->devices[i];
>>>> +        if (dev->type == NPU2_DEV_TYPE_UNKNOWN)
>>>> +            continue;
>>>> +
>>>> +        switch (dev->brick_index) {
>>>> +        case 0:  /* NTL0.0 */
>>>> +            assert(dev->type == NPU2_DEV_TYPE_NVLINK);
>>>> +            ndlmux_brk0to2 |= 0b100;
>>>> +            break;
>>>> +        case 1:  /* NTL0.1 */
>>>> +            assert(dev->type == NPU2_DEV_TYPE_NVLINK);
>>>> +            ndlmux_brk0to2 |= 0b010;
>>>> +            break;
>>>> +        case 2:     /* NTL1.0 / OTL1.0 */
>>>> +            if (dev->type == NPU2_DEV_TYPE_OPENCAPI) {
>>>> +                ndlmux_brk0to2 &= ~0b100;
>>>> +                ocmux_brk0to1 |= 0b10;
>>>> +            } else {
>>>> +                ndlmux_brk0to2 |= 0b001;
>>>> +            }
>>>> +            break;
>>>> +        case 3:     /* NTL1.1 / OTL1.1 */
>>>> +            if (dev->type == NPU2_DEV_TYPE_OPENCAPI) {
>>>> +                ndlmux_brk0to2 &= ~0b010;
>>>> +                ocmux_brk0to1 |= 0b01;
>>>> +            }
>>>> +            break;
>>>> +        case 4:     /* NTL2.0 / OTL2.0 */
>>>> +            if (dev->type == NPU2_DEV_TYPE_OPENCAPI) {
>>>> +                ocmux_brk4to5 |= 0b10;
>>>> +            } else {
>>>> +                ocmux_brk4to5 &= ~0b10;
>>>> +            }
>>>> +            break;
>>>> +        case 5:     /* NTL2.1 / OTL2.1 */
>>>> +            if (dev->type == NPU2_DEV_TYPE_OPENCAPI) {
>>>> +                ocmux_brk4to5 |= 0b01;
>>>> +            } else {
>>>> +                ocmux_brk4to5 &= ~0b01;
>>>> +            }
>>>> +            break;
>>>> +        default:
>>>> +            assert(false);
>>>> +        }
>>>> +    }
>>>> +
>>>> +    reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_NDLMUX_BRK0TO2, reg, 
>>>> ndlmux_brk0to2);
>>>> +    reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK0TO1, reg, 
>>>> ocmux_brk0to1);
>>>> +    reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK4TO5, reg, 
>>>> ocmux_brk4to5);
>>>> +    npu2_scom_write(npu->chip_id, npu->xscom_base, 
>>>> NPU2_MISC_OPTICAL_IO_CFG0,
>>>> +            NPU2_MISC_DA_LEN_8B, reg);
>>>> +
>>>> +    /*
>>>> +     * PowerBus Optical Miscellaneous Config Register
>>>> +     */
>>>> +    xscom_read(npu->chip_id, PU_IOE_PB_MISC_CFG, &reg);
>>>> +    for (int i = 0; i < npu->total_devices; i++) {
>>>> +        dev = &npu->devices[i];
>>>> +        switch (dev->brick_index) {
>>>> +        case 3:
>>>> +            if (dev->type == NPU2_DEV_TYPE_NVLINK)
>>>> +                reg = 
>>>> SETFIELD(PU_IOE_PB_MISC_CFG_SEL_03_NPU_NOT_PB, reg, 1);
>>>> +            break;
>>>> +        case 4:
>>>> +            reg = SETFIELD(PU_IOE_PB_MISC_CFG_SEL_04_NPU_NOT_PB, 
>>>> reg, 1);
>>>> +            break;
>>>> +        case 5:
>>>> +            reg = SETFIELD(PU_IOE_PB_MISC_CFG_SEL_05_NPU_NOT_PB, 
>>>> reg, 1);
>>>> +            break;
>>>> +        default:
>>>> +            break;
>>>> +        }
>>>> +    }
>>>> +    xscom_write(npu->chip_id, PU_IOE_PB_MISC_CFG, reg);
>>>> +}
>>>> +
>>>>   static struct npu2 *setup_npu(struct dt_node *dn)
>>>>   {
>>>>       struct npu2 *npu;
>>>> @@ -212,6 +336,7 @@ static struct npu2 *setup_npu(struct dt_node *dn)
>>>>           dev->link_index = dt_prop_get_u32(np, "ibm,npu-link-index");
>>>>           /* May be overridden by platform presence detection */
>>>>           dev->brick_index = dev->link_index;
>>>> +        dev->group_id = dt_prop_get_u32(np, "ibm,npu-group-id");
>>>>           /* Will be overridden by presence detection */
>>>>           dev->type = NPU2_DEV_TYPE_UNKNOWN;
>>>>           dev->npu = npu;
>>>> @@ -313,6 +438,7 @@ void probe_npu2(void)
>>>>           if (!npu)
>>>>               continue;
>>>>           platform.npu2_device_detect(npu);
>>>> +        set_brick_config(npu);
>>>>           setup_devices(npu);
>>>>       }
>>>>   }
>>>> diff --git a/hw/npu2-opencapi.c b/hw/npu2-opencapi.c
>>>> index 8c4f34622c50..76b81d679046 100644
>>>> --- a/hw/npu2-opencapi.c
>>>> +++ b/hw/npu2-opencapi.c
>>>> @@ -150,112 +150,6 @@ static uint64_t get_odl_status(uint32_t gcid, 
>>>> uint64_t index) {
>>>>       return reg;
>>>>   }
>>>>
>>>> -static void disable_nvlink(uint32_t gcid, int index)
>>>> -{
>>>> -    uint64_t phy_config_scom, reg;
>>>> -
>>>> -    switch (index) {
>>>> -    case 2:
>>>> -    case 3:
>>>> -        phy_config_scom = OBUS_LL0_IOOL_PHY_CONFIG;
>>>> -        break;
>>>> -    case 4:
>>>> -    case 5:
>>>> -        phy_config_scom = OBUS_LL3_IOOL_PHY_CONFIG;
>>>> -        break;
>>>> -    default:
>>>> -        assert(false);
>>>> -    }
>>>> -    /* Disable NV-Link link layers */
>>>> -    xscom_read(gcid, phy_config_scom, &reg);
>>>> -    reg &= ~OBUS_IOOL_PHY_CONFIG_NV0_NPU_ENABLED;
>>>> -    reg &= ~OBUS_IOOL_PHY_CONFIG_NV1_NPU_ENABLED;
>>>> -    reg &= ~OBUS_IOOL_PHY_CONFIG_NV2_NPU_ENABLED;
>>>> -    xscom_write(gcid, phy_config_scom, reg);
>>>> -}
>>>> -
>>>> -/* Procedure 13.1.3.1 - select OCAPI vs NVLink for bricks 2-3/4-5 */
>>>> -
>>>> -static void set_transport_mux_controls(uint32_t gcid, uint32_t 
>>>> scom_base,
>>>> -                       int index, enum npu2_dev_type type)
>>>> -{
>>>> -    /* Step 1 - Set Transport MUX controls to select correct OTL or 
>>>> NTL */
>>>> -    uint64_t reg;
>>>> -    uint64_t field;
>>>> -
>>>> -    /* TODO: Rework this to select for NVLink too */
>>>> -    assert(type == NPU2_DEV_TYPE_OPENCAPI);
>>>> -
>>>> -    prlog(PR_DEBUG, "OCAPI: %s: Setting transport mux controls\n", 
>>>> __func__);
>>>> -
>>>> -    /* Optical IO Transport Mux Config for Bricks 0-2 and 4-5 */
>>>> -    reg = npu2_scom_read(gcid, scom_base, NPU2_MISC_OPTICAL_IO_CFG0,
>>>> -                 NPU2_MISC_DA_LEN_8B);
>>>> -    switch (index) {
>>>> -    case 0:
>>>> -    case 1:
>>>> -        /* not valid for OpenCAPI */
>>>> -        assert(false);
>>>> -        break;
>>>> -    case 2:     /* OTL1.0 */
>>>> -        field = GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_NDLMUX_BRK0TO2, 
>>>> reg);
>>>> -        field &= ~0b100;
>>>> -        reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_NDLMUX_BRK0TO2, reg,
>>>> -                   field);
>>>> -        field = GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK0TO1, 
>>>> reg);
>>>> -        field |= 0b10;
>>>> -        reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK0TO1, reg,
>>>> -                   field);
>>>> -        break;
>>>> -    case 3:     /* OTL1.1 */
>>>> -        field = GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_NDLMUX_BRK0TO2, 
>>>> reg);
>>>> -        field &= ~0b010;
>>>> -        reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_NDLMUX_BRK0TO2, reg,
>>>> -                   field);
>>>> -        field = GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK0TO1, 
>>>> reg);
>>>> -        field |= 0b01;
>>>> -        reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK0TO1, reg,
>>>> -                   field);
>>>> -        break;
>>>> -    case 4:     /* OTL2.0 */
>>>> -        field = GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK4TO5, 
>>>> reg);
>>>> -        field |= 0b10;
>>>> -        reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK4TO5, reg,
>>>> -                   field);
>>>> -        break;
>>>> -    case 5:     /* OTL2.1 */
>>>> -        field = GETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK4TO5, 
>>>> reg);
>>>> -        field |= 0b01;
>>>> -        reg = SETFIELD(NPU2_MISC_OPTICAL_IO_CFG0_OCMUX_BRK4TO5, reg,
>>>> -                   field);
>>>> -        break;
>>>> -    default:
>>>> -        assert(false);
>>>> -    }
>>>> -    npu2_scom_write(gcid, scom_base, NPU2_MISC_OPTICAL_IO_CFG0,
>>>> -            NPU2_MISC_DA_LEN_8B, reg);
>>>> -
>>>> -    /*
>>>> -     * PowerBus Optical Miscellaneous Config Register - select
>>>> -     * OpenCAPI for b4/5 and A-Link for b3
>>>> -     */
>>>> -    xscom_read(gcid, PU_IOE_PB_MISC_CFG, &reg);
>>>> -    switch (index) {
>>>> -    case 0:
>>>> -    case 1:
>>>> -    case 2:
>>>> -    case 3:
>>>> -        break;
>>>> -    case 4:
>>>> -        reg = SETFIELD(PU_IOE_PB_MISC_CFG_SEL_04_NPU_NOT_PB, reg, 1);
>>>> -        break;
>>>> -    case 5:
>>>> -        reg = SETFIELD(PU_IOE_PB_MISC_CFG_SEL_05_NPU_NOT_PB, reg, 1);
>>>> -        break;
>>>> -    }
>>>> -    xscom_write(gcid, PU_IOE_PB_MISC_CFG, reg);
>>>> -}
>>>> -
>>>>   static void enable_odl_phy_mux(uint32_t gcid, int index)
>>>>   {
>>>>       uint64_t reg;
>>>> @@ -533,9 +427,6 @@ static void brick_config(uint32_t gcid, uint32_t 
>>>> scom_base, int index)
>>>>        * We assume at this point that the PowerBus Hotplug Mode Control
>>>>        * register is correctly set by Hostboot
>>>>        */
>>>> -    disable_nvlink(gcid, index);
>>>> -    set_transport_mux_controls(gcid, scom_base, index,
>>>> -                   NPU2_DEV_TYPE_OPENCAPI);
>>>>       enable_odl_phy_mux(gcid, index);
>>>>       disable_alink_fp(gcid);
>>>>       enable_xsl_clocks(gcid, scom_base, index);
>>>> diff --git a/hw/npu2.c b/hw/npu2.c
>>>> index d7d9435741d6..5b06edc4603f 100644
>>>> --- a/hw/npu2.c
>>>> +++ b/hw/npu2.c
>>>> @@ -1356,6 +1356,62 @@ static void assign_mmio_bars(uint64_t gcid, 
>>>> uint32_t scom, uint64_t reg[2], uint
>>>>               mm_win[0];
>>>>   }
>>>>
>>>> +static void enable_nvlink(struct npu2_dev *dev)
>>>> +{
>>>> +    struct npu2 *npu = dev->npu;
>>>> +    int stack = NPU2_STACK_STCK_0 + NPU2DEV_STACK(dev);
>>>> +    int block;
>>>> +    uint64_t addr, val;
>>>> +
>>>> +    /* CQ_SM Misc Config #0 - enable NVLink mode */
>>>> +    for (block = NPU2_BLOCK_SM_0; block <= NPU2_BLOCK_SM_3; block++) {
>>>> +        addr = NPU2_REG_OFFSET(stack, block, NPU2_CQ_SM_MISC_CFG0);
>>>> +        val = npu2_scom_read(npu->chip_id, npu->xscom_base, addr,
>>>> +                     NPU2_MISC_DA_LEN_8B);
>>>> +        val |= NPU2_CQ_SM_MISC_CFG0_CONFIG_NVLINK_MODE;
>>>> +        npu2_scom_write(npu->chip_id, npu->xscom_base, addr,
>>>> +                NPU2_MISC_DA_LEN_8B, val);
>>>> +    }
>>>> +
>>>> +    /* CQ_CTL Misc Config #0 - enable NVLink mode */
>>>> +    addr = NPU2_REG_OFFSET(stack, NPU2_BLOCK_CTL, 
>>>> NPU2_CQ_CTL_MISC_CFG);
>>>> +    val = npu2_scom_read(npu->chip_id, npu->xscom_base, addr,
>>>> +                 NPU2_MISC_DA_LEN_8B);
>>>> +    val |= NPU2_CQ_CTL_MISC_CFG_CONFIG_NVLINK_MODE;
>>>> +    npu2_scom_write(npu->chip_id, npu->xscom_base, addr,
>>>> +            NPU2_MISC_DA_LEN_8B, val);
>>>> +
>>>> +    /* CQ_DAT Misc Config #1 - enable NVLink mode */
>>>> +    addr = NPU2_REG_OFFSET(stack, NPU2_BLOCK_DAT, 
>>>> NPU2_CQ_DAT_MISC_CFG);
>>>> +    val = npu2_scom_read(npu->chip_id, npu->xscom_base, addr,
>>>> +                 NPU2_MISC_DA_LEN_8B);
>>>> +    val |= NPU2_CQ_DAT_MISC_CFG_CONFIG_NVLINK_MODE;
>>>> +    npu2_scom_write(npu->chip_id, npu->xscom_base, addr,
>>>> +            NPU2_MISC_DA_LEN_8B, val);
>>>> +
>>>> +    /* NTL Misc Config 2 - enable NTL brick and checks */
>>>> +    addr = NPU2_NTL_MISC_CFG2(dev);
>>>> +    val = npu2_scom_read(npu->chip_id, npu->xscom_base, addr,
>>>> +                 NPU2_MISC_DA_LEN_8B);
>>>> +    val |= NPU2_NTL_MISC_CFG2_BRICK_ENABLE;
>>>> +    val |= NPU2_NTL_MISC_CFG2_NDL_TX_PARITY_ENA;
>>>> +    val |= NPU2_NTL_MISC_CFG2_NDL_PRI_PARITY_ENA;
>>>> +    val |= NPU2_NTL_MISC_CFG2_RCV_CREDIT_OVERFLOW_ENA;
>>>> +    npu2_scom_write(npu->chip_id, npu->xscom_base, addr,
>>>> +            NPU2_MISC_DA_LEN_8B, val);
>>>> +
>>>> +    /* High Water Marks */
>>>> +    for (block = NPU2_BLOCK_SM_0; block <= NPU2_BLOCK_SM_3; block++) {
>>>> +        addr = NPU2_REG_OFFSET(stack, block, NPU2_HIGH_WATER_MARKS);
>>>> +        val = npu2_scom_read(npu->chip_id, npu->xscom_base, addr,
>>>> +                     NPU2_MISC_DA_LEN_8B);
>>>> +        val &= ~NPU2_HIGH_WATER_MARKS_PWR0;
>>>> +        val |= PPC_BIT(6) | PPC_BIT(7) | PPC_BIT(11);
>>>> +        npu2_scom_write(npu->chip_id, npu->xscom_base, addr,
>>>> +                NPU2_MISC_DA_LEN_8B, val);
>>>> +    }
>>>> +}
>>>> +
>>>>   /*
>>>>    * Set up NPU for NVLink and create PCI root device node
>>>>    * accordingly.
>>>> @@ -1363,59 +1419,12 @@ static void assign_mmio_bars(uint64_t gcid, 
>>>> uint32_t scom, uint64_t reg[2], uint
>>>>   int npu2_nvlink_init_npu(struct npu2 *npu)
>>>>   {
>>>>       struct dt_node *np;
>>>> -    uint64_t reg[2], mm_win[2], val;
>>>> +    uint64_t reg[2], mm_win[2];
>>>>
>>>> -    /* TODO: Clean this up with register names, etc. when we get
>>>> -     * time. This just turns NVLink mode on in each brick and should
>>>> -     * get replaced with a patch from ajd once we've worked out how
>>>> -     * things are going to work there.
>>>> -     *
>>>> -     * Obviously if the year is now 2020 that didn't happen and you
>>>> -     * should fix this :-) */
>>>> -    xscom_write_mask(npu->chip_id, 0x5011000, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011030, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011060, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011090, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011200, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011230, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011260, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011290, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011400, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011430, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011460, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011490, PPC_BIT(58), 
>>>> PPC_BIT(58));
>>>> -
>>>> -    xscom_write_mask(npu->chip_id, 0x50110c0, PPC_BIT(53), 
>>>> PPC_BIT(53));
>>>> -    xscom_write_mask(npu->chip_id, 0x50112c0, PPC_BIT(53), 
>>>> PPC_BIT(53));
>>>> -    xscom_write_mask(npu->chip_id, 0x50114c0, PPC_BIT(53), 
>>>> PPC_BIT(53));
>>>> -    xscom_write_mask(npu->chip_id, 0x50110f1, PPC_BIT(41), 
>>>> PPC_BIT(41));
>>>> -    xscom_write_mask(npu->chip_id, 0x50112f1, PPC_BIT(41), 
>>>> PPC_BIT(41));
>>>> -    xscom_write_mask(npu->chip_id, 0x50114f1, PPC_BIT(41), 
>>>> PPC_BIT(41));
>>>> -
>>>> -    val = NPU2_NTL_MISC_CFG2_BRICK_ENABLE |
>>>> -          NPU2_NTL_MISC_CFG2_NDL_TX_PARITY_ENA |
>>>> -          NPU2_NTL_MISC_CFG2_NDL_PRI_PARITY_ENA |
>>>> -          NPU2_NTL_MISC_CFG2_RCV_CREDIT_OVERFLOW_ENA;
>>>> -    xscom_write_mask(npu->chip_id, 0x5011110, val, val);
>>>> -    xscom_write_mask(npu->chip_id, 0x5011130, val, val);
>>>> -    xscom_write_mask(npu->chip_id, 0x5011310, val, val);
>>>> -    xscom_write_mask(npu->chip_id, 0x5011330, val, val);
>>>> -    xscom_write_mask(npu->chip_id, 0x5011510, val, val);
>>>> -    xscom_write_mask(npu->chip_id, 0x5011530, val, val);
>>>> -
>>>> -    val = PPC_BIT(6) | PPC_BIT(7) | PPC_BIT(11);
>>>> -    xscom_write_mask(npu->chip_id, 0x5011009, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011039, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011069, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011099, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011209, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011239, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011269, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011299, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011409, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011439, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011469, val, PPC_BITMASK(6,11));
>>>> -    xscom_write_mask(npu->chip_id, 0x5011499, val, PPC_BITMASK(6,11));
>>>> +    for (int i = 0; i < npu->total_devices; i++) {
>>>> +        if (npu->devices[i].type == NPU2_DEV_TYPE_NVLINK)
>>>> +            enable_nvlink(&npu->devices[i]);
>>>> +    }
>>>>
>>>>       /* Reassign the BARs */
>>>>       assign_mmio_bars(npu->chip_id, npu->xscom_base, reg, mm_win);
>>>> @@ -1650,12 +1659,15 @@ static void npu2_populate_cfg(struct 
>>>> npu2_dev *dev)
>>>>       PCI_VIRT_CFG_INIT_RO(pvd, pos + 1, 1, 0);
>>>>   }
>>>>
>>>> -static uint32_t npu_allocate_bdfn(struct npu2 *p, uint32_t group)
>>>> +static uint32_t npu_allocate_bdfn(struct npu2 *p, uint32_t group, 
>>>> int device_num)
>>>>   {
>>>>       int i;
>>>>       int bdfn = (group << 3);
>>>>
>>>> -    for (i = 0; i < p->total_devices; i++) {
>>>> +    for (i = 0; i < device_num; i++) {
>>>> +        if (p->devices[i].type != NPU2_DEV_TYPE_NVLINK)
>>>> +            continue;
>>>> +
>>>>           if ((p->devices[i].bdfn & 0xf8) == (bdfn & 0xf8))
>>>>               bdfn++;
>>>>       }
>>>> @@ -1663,46 +1675,24 @@ static uint32_t npu_allocate_bdfn(struct 
>>>> npu2 *p, uint32_t group)
>>>>       return bdfn;
>>>>   }
>>>>
>>>> -static void npu2_populate_devices(struct npu2 *p,
>>>> -                  struct dt_node *dn)
>>>> +static void npu2_populate_devices(struct npu2 *npu)
>>>>   {
>>>>       struct npu2_dev *dev;
>>>> -    struct dt_node *npu2_dn, *link;
>>>> -    uint32_t npu_phandle, index = 0;
>>>> +    struct npu2_bar *npu2_bar;
>>>>       int stack;
>>>>
>>>> -    /*
>>>> -     * Get the npu node which has the links which we expand here
>>>> -     * into pci like devices attached to our emulated phb.
>>>> -     */
>>>> -    npu_phandle = dt_prop_get_u32(dn, "ibm,npcq");
>>>> -    npu2_dn = dt_find_by_phandle(dt_root, npu_phandle);
>>>> -    assert(npu2_dn);
>>>> -
>>>> -    /* Walk the link at x nodes to initialize devices */
>>>> -    p->total_devices = 0;
>>>> -    p->phb_nvlink.scan_map = 0;
>>>> -    dt_for_each_compatible(npu2_dn, link, "ibm,npu-link") {
>>>> -        uint32_t group_id;
>>>> -        struct npu2_bar *npu2_bar;
>>>> +    npu->phb_nvlink.scan_map = 0;
>>>> +    for (int i = 0; i < npu->total_devices; i++) {
>>>> +        dev = &npu->devices[i];
>>>>
>>>> -        dev = &p->devices[index];
>>>> -        dev->type = NPU2_DEV_TYPE_NVLINK;
>>>> -        dev->npu = p;
>>>> -        dev->dt_node = link;
>>>> -        dev->link_index = dt_prop_get_u32(link, "ibm,npu-link-index");
>>>> -        dev->brick_index = dev->link_index;
>>>> +        if (dev->type != NPU2_DEV_TYPE_NVLINK)
>>>> +            continue;
>>>>
>>>> -        group_id = dt_prop_get_u32(link, "ibm,npu-group-id");
>>>> -        dev->bdfn = npu_allocate_bdfn(p, group_id);
>>>> +        dev->bdfn = npu_allocate_bdfn(npu, dev->group_id, i);
>>>>
>>>>           /* This must be done after calling
>>>>            * npu_allocate_bdfn() */
>>>> -        p->total_devices++;
>>>> -        p->phb_nvlink.scan_map |= 0x1 << ((dev->bdfn & 0xf8) >> 3);
>>>> -
>>>> -        dev->pl_xscom_base = dt_prop_get_u64(link, "ibm,npu-phy");
>>>> -        dev->lane_mask = dt_prop_get_u32(link, "ibm,npu-lane-mask");
>>>> +        npu->phb_nvlink.scan_map |= 0x1 << ((dev->bdfn & 0xf8) >> 3);
>>>>
>>>>           /* Populate BARs. BAR0/1 is the NTL bar. */
>>>>           stack = NPU2_STACK_STCK_0 + NPU2DEV_STACK(dev);
>>>> @@ -1711,7 +1701,7 @@ static void npu2_populate_devices(struct npu2 *p,
>>>>           npu2_bar->index = dev->brick_index;
>>>>           npu2_bar->reg = NPU2_REG_OFFSET(stack, 0, 
>>>> NPU2DEV_BRICK(dev) == 0 ?
>>>>                           NPU2_NTL0_BAR : NPU2_NTL1_BAR);
>>>> -            npu2_get_bar(p->chip_id, npu2_bar);
>>>> +            npu2_get_bar(npu->chip_id, npu2_bar);
>>>>
>>>>           dev->bars[0].flags = PCI_CFG_BAR_TYPE_MEM | 
>>>> PCI_CFG_BAR_MEM64;
>>>>
>>>> @@ -1720,7 +1710,7 @@ static void npu2_populate_devices(struct npu2 *p,
>>>>           npu2_bar->type = NPU_GENID;
>>>>           npu2_bar->index = NPU2DEV_STACK(dev);
>>>>           npu2_bar->reg = NPU2_REG_OFFSET(stack, 0, NPU2_GENID_BAR);
>>>> -            npu2_get_bar(p->chip_id, npu2_bar);
>>>> +            npu2_get_bar(npu->chip_id, npu2_bar);
>>>>
>>>>           /* The GENID is a single physical BAR that we split
>>>>            * for each emulated device */
>>>> @@ -1730,14 +1720,13 @@ static void npu2_populate_devices(struct 
>>>> npu2 *p,
>>>>           dev->bars[1].flags = PCI_CFG_BAR_TYPE_MEM | 
>>>> PCI_CFG_BAR_MEM64;
>>>>
>>>>           /* Initialize PCI virtual device */
>>>> -        dev->nvlink.pvd = pci_virt_add_device(&p->phb_nvlink, 
>>>> dev->bdfn, 0x100, dev);
>>>> +        dev->nvlink.pvd = pci_virt_add_device(&npu->phb_nvlink,
>>>> +                              dev->bdfn, 0x100, dev);
>>>>           if (dev->nvlink.pvd) {
>>>> -            p->phb_nvlink.scan_map |=
>>>> +            npu->phb_nvlink.scan_map |=
>>>>                   0x1 << ((dev->nvlink.pvd->bdfn & 0xf8) >> 3);
>>>>               npu2_populate_cfg(dev);
>>>>           }
>>>> -
>>>> -        index++;
>>>>       }
>>>>   }
>>>>
>>>> @@ -1928,7 +1917,7 @@ void npu2_nvlink_create_phb(struct npu2 *npu, 
>>>> struct dt_node *dn)
>>>>       list_head_init(&npu->phb_nvlink.virt_devices);
>>>>
>>>>       npu2_setup_irqs(npu);
>>>> -    npu2_populate_devices(npu, dn);
>>>> +    npu2_populate_devices(npu);
>>>>       npu2_add_interrupt_map(npu, dn);
>>>>       npu2_add_phb_properties(npu);
>>>>
>>>> diff --git a/include/npu2-regs.h b/include/npu2-regs.h
>>>> index 8c1ba5fff37a..482b8e47af0d 100644
>>>> --- a/include/npu2-regs.h
>>>> +++ b/include/npu2-regs.h
>>>> @@ -119,6 +119,7 @@ void npu2_scom_write(uint64_t gcid, uint64_t 
>>>> scom_base,
>>>>   #define NPU2_CQ_SM_MISC_CFG0            0x000
>>>>   #define   NPU2_CQ_SM_MISC_CFG0_CONFIG_ENABLE_PBUS PPC_BIT(38)
>>>>   #define   NPU2_CQ_SM_MISC_CFG0_CONFIG_OCAPI_MODE PPC_BIT(57)
>>>> +#define   NPU2_CQ_SM_MISC_CFG0_CONFIG_NVLINK_MODE PPC_BIT(58)
>>>>   #define NPU2_CQ_SM_MISC_CFG1            0x008
>>>>   #define NPU2_CQ_SM_MISC_CFG2            0x148
>>>>   #define NPU2_PB_EPSILON                0x010
>>>> @@ -152,6 +153,7 @@ void npu2_scom_write(uint64_t gcid, uint64_t 
>>>> scom_base,
>>>>   #define NPU2_LOW_WATER_MARKS            0x040
>>>>   #define   NPU2_LOW_WATER_MARKS_ENABLE_MACHINE_ALLOC PPC_BIT(51)
>>>>   #define NPU2_HIGH_WATER_MARKS            0x048
>>>> +#define   NPU2_HIGH_WATER_MARKS_PWR0        PPC_BITMASK(6, 11);
>>>>   #define NPU2_RELAXED_ORDERING_CFG(n)        (0x050 + (n)*8)
>>>>   #define   NPU2_RELAXED_ORDERING_SOURCE(n)    (PPC_BITMASK(0,31) >> 
>>>> ((n)*32))
>>>>   #define     NPU2_RELAXED_ORDERING_SOURCE_ENA    PPC_BITMASK32(0,3)
>>>> @@ -207,6 +209,7 @@ void npu2_scom_write(uint64_t gcid, uint64_t 
>>>> scom_base,
>>>>   /* CTL block registers */
>>>>   #define NPU2_CQ_CTL_MISC_CFG            0x000
>>>>   #define   NPU2_CQ_CTL_MISC_CFG_CONFIG_OCAPI_MODE PPC_BIT(52)
>>>> +#define   NPU2_CQ_CTL_MISC_CFG_CONFIG_NVLINK_MODE PPC_BIT(53)
>>>>   #define   NPU2_CQ_CTL_MISC_CFG_CONFIG_OTL0_ENABLE PPC_BIT(55)
>>>>   #define   NPU2_CQ_CTL_MISC_CFG_CONFIG_OTL1_ENABLE PPC_BIT(56)
>>>>   #define NPU2_CQ_CTL_MISC_MMIOPA0_CONFIG        0x0B0
>>>> @@ -261,6 +264,7 @@ void npu2_scom_write(uint64_t gcid, uint64_t 
>>>> scom_base,
>>>>   /* DAT block registers */
>>>>   #define NPU2_CQ_DAT_MISC_CFG            0x008
>>>>   #define      NPU2_CQ_DAT_MISC_CFG_CONFIG_OCAPI_MODE PPC_BIT(40)
>>>> +#define      NPU2_CQ_DAT_MISC_CFG_CONFIG_NVLINK_MODE PPC_BIT(41)
>>>>   #define NPU2_CQ_DAT_ECC_CFG            0x010
>>>>   #define NPU2_CQ_DAT_SCRATCH0            0x018
>>>>   #define NPU2_CQ_DAT_ECC_STATUS            0x020
>>>> diff --git a/include/npu2.h b/include/npu2.h
>>>> index 1de963d19928..252390be2269 100644
>>>> --- a/include/npu2.h
>>>> +++ b/include/npu2.h
>>>> @@ -122,6 +122,7 @@ struct npu2_dev {
>>>>       enum npu2_dev_type    type;
>>>>       uint32_t        link_index;
>>>>       uint32_t        brick_index;
>>>> +    uint32_t        group_id;
>>>>       uint64_t        pl_xscom_base;
>>>>       struct dt_node        *dt_node;
>>>>       struct npu2_pcie_bar    bars[2];
>>>>
>>



More information about the Skiboot mailing list