in hw/intel/ntb_hw_gen4.c [416:478]
static int intel_ntb4_link_enable(struct ntb_dev *ntb,
enum ntb_speed max_speed, enum ntb_width max_width)
{
struct intel_ntb_dev *ndev;
u32 ntb_ctl, ppd0;
u16 lnkctl;
ndev = container_of(ntb, struct intel_ntb_dev, ntb);
dev_dbg(&ntb->pdev->dev,
"Enabling link with max_speed %d max_width %d\n",
max_speed, max_width);
if (max_speed != NTB_SPEED_AUTO)
dev_dbg(&ntb->pdev->dev,
"ignoring max_speed %d\n", max_speed);
if (max_width != NTB_WIDTH_AUTO)
dev_dbg(&ntb->pdev->dev,
"ignoring max_width %d\n", max_width);
if (!(ndev->hwerr_flags & NTB_HWERR_LTR_BAD)) {
u32 ltr;
/* Setup active snoop LTR values */
ltr = NTB_LTR_ACTIVE_REQMNT | NTB_LTR_ACTIVE_VAL | NTB_LTR_ACTIVE_LATSCALE;
/* Setup active non-snoop values */
ltr = (ltr << NTB_LTR_NS_SHIFT) | ltr;
iowrite32(ltr, ndev->self_mmio + GEN4_LTR_ACTIVE_OFFSET);
/* Setup idle snoop LTR values */
ltr = NTB_LTR_IDLE_VAL | NTB_LTR_IDLE_LATSCALE | NTB_LTR_IDLE_REQMNT;
/* Setup idle non-snoop values */
ltr = (ltr << NTB_LTR_NS_SHIFT) | ltr;
iowrite32(ltr, ndev->self_mmio + GEN4_LTR_IDLE_OFFSET);
/* setup PCIe LTR to active */
iowrite8(NTB_LTR_SWSEL_ACTIVE, ndev->self_mmio + GEN4_LTR_SWSEL_OFFSET);
}
ntb_ctl = NTB_CTL_E2I_BAR23_SNOOP | NTB_CTL_I2E_BAR23_SNOOP;
ntb_ctl |= NTB_CTL_E2I_BAR45_SNOOP | NTB_CTL_I2E_BAR45_SNOOP;
iowrite32(ntb_ctl, ndev->self_mmio + ndev->reg->ntb_ctl);
lnkctl = ioread16(ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
lnkctl &= ~GEN4_LINK_CTRL_LINK_DISABLE;
iowrite16(lnkctl, ndev->self_mmio + GEN4_LINK_CTRL_OFFSET);
/* start link training in PPD0 */
ppd0 = ioread32(ndev->self_mmio + GEN4_PPD0_OFFSET);
ppd0 |= GEN4_PPD_LINKTRN;
iowrite32(ppd0, ndev->self_mmio + GEN4_PPD0_OFFSET);
/* make sure link training has started */
ppd0 = ioread32(ndev->self_mmio + GEN4_PPD0_OFFSET);
if (!(ppd0 & GEN4_PPD_LINKTRN)) {
dev_warn(&ntb->pdev->dev, "Link is not training\n");
return -ENXIO;
}
ndev->dev_up = 1;
return 0;
}